Create two table parent and child
Create table parent (ID int, ParentId int,Text varchar(20))
Create table Child (child1Id int, ParentId int, point int)
ID ParentId Text
1 NULL Sony
2 1 phone
3 2 sale
4 2 Rate
child1Id ParentIdId point
100 3 10
200 4 20
I tried something like this
Select sum(b.point),a.ParentId,a.Text from parent A join Child B on a.ID =b.ParentId group by a.ParentId,a.Text
I need output like this.
ID ParentId Text Point
1 NULL Sony null
2 1 phone 30
You can do this with a subquery
SELECT p.ID
, p.parentId
, p.[Text] AS 'Text'
, cld.pointSum AS 'Point'
FROM dbo.Parent AS p
LEFT JOIN (
SELECT c.ParentId
, SUM(c.point) AS 'pointSum'
FROM dbo.Child AS c
GROUP BY c.ParentId
) cld ON (p.ID = cld.ParentId)
Related
I couldn't find that via search, so I guess I am not asking it the right way, so help is welcome.
We have a lookup table:
Id Name
------------------
1 "Test"
2 "New"
3 "InProgress"
Table2:
StatusId SomethingElse
1
2
Table 1
ID Other Other StatusId (Fkey to Table2) ...
Then we have a view that selects from several tables and one of the columns is a CASE Statement:
SELECT * FROM Table1 t1 -- has million records
CASE When t1.StatusId = 1 THEN (SELECT Name from LOOKUP table where ID = 1) END --'Test'
CASE When t1.StatusId = 2 THEN (SELECT Name from LOOKUP table where ID = 2) END --'New'
CASE When t3.Date is not null THEN (SELECT Name from LOOKUP table where ID = 3) END --'In Progress'
-- AND ALSO the case look at other tables another 5-6 tables and there are conditions from there
INNER JOIN Table2 t2 on ...
INNER JOIN Table3 t3 on ...
As you see these are really static values.
I want to load them once into variables, e.g.
#LookUp1 = SELECT [NAME] FROM LookUP WHERE Id = 1,
#LookUp2 = SELECT [NAME] FROM LookUP WHERE Id = 2
and replace the select in the CASE statement to this:
When StatusId = 1 THEN #LookUp
When StatusId = 2 THEN #LookUp2
The view loops through millions of records and it gets really slow to do the select from Lookup table for every row.
Why not simply use a join?
SELECT <columns list from main table>, Lt.Name
FROM <main table> As Mt -- Do not use such aliases in real code!
JOIN <SecondaryTable> As St -- this represents your Table3
ON <condition>
[LEFT] JOIN <Lookup table> As Lt
ON Mt.StatusId = Lt.Id
OR (Lt.Id = 3 AND St.Date is not null)
Of course, replace <columns list from main table> with the actual columns list, <main table> with the name of the main table and so on.
The join might be an inner or left join, depending on the nullability of the StatusId column in the main table and if it's nullable, on what you want to get in such cases (either a row with null name or no row at all).
I've put together a little demonstration to show you exactly what I mean.
Create and populate sample tables (Please save us this step in your future questions):
CREATE TABLE LookUp (Id int, Name varchar(10));
INSERT INTO LookUp (Id, Name) VALUES
(1, 'Test'), (2, 'New'), (3, 'InProgress');
CREATE TABLE Table1 (Id int not null, StatusId int null);
INSERT INTO Table1(Id, StatusId)
SELECT n, CASE WHEN n % 3 = 0 THEN NULL ELSE (n % 3) END
FROM
(
SELECT TOP 30 ROW_NUMBER() OVER(ORDER BY ##SPID) As n
FROM sys.objects
) tally
CREATE TABLE Table3
(
Id int not null,
Date date null
)
INSERT INTO Table3 (Id, Date)
SELECT Id, CASE WHEN StatusId IS NULL AND Id % 4 = 0 THEN GetDate() END
FROM Table1
The query:
SELECT Table1.Id,
Table1.StatusId,
Table3.Date,
LookUp.Name
FROM Table1
JOIN Table3
ON Table1.Id = Table3.Id
LEFT JOIN LookUp
ON Table1.StatusId = LookUp.Id
OR (LookUp.Id = 3 AND Table3.Date IS NOT NULL)
Results:
Id StatusId Date Name
1 1 NULL Test
2 2 NULL New
3 NULL NULL NULL
4 1 NULL Test
5 2 NULL New
6 NULL NULL NULL
7 1 NULL Test
8 2 NULL New
9 NULL NULL NULL
10 1 NULL Test
11 2 NULL New
12 NULL 27.06.2019 InProgress
13 1 NULL Test
14 2 NULL New
15 NULL NULL NULL
16 1 NULL Test
17 2 NULL New
18 NULL NULL NULL
19 1 NULL Test
20 2 NULL New
21 NULL NULL NULL
22 1 NULL Test
23 2 NULL New
24 NULL 27.06.2019 InProgress
25 1 NULL Test
26 2 NULL New
27 NULL NULL NULL
28 1 NULL Test
29 2 NULL New
30 NULL NULL NULL
You can also see a live demo on rextester.
Create a SQL function which return Name according to Id.
Create FUNCTION [dbo].[GetLookUpValue]
(
#Id int
)
RETURNS varchar(500)
AS BEGIN
return(Select Name from LOOKUP_table with(nolock) where Id=#Id)
END
I have this code
create table #temp
(
order_id int not null identity(1,1) primary key
,sid int
,created_date date
,parent_order_id int
)
insert into #temp
(
sid
,created_date
)values(1,'2017-01-01')
insert into #temp
(
sid
,created_date
,parent_order_id
)values(1,'2017-02-01',1),(1,'2017-03-01',2),(1,'2017-04-01',3)
insert into #temp
(
sid
,created_date
)values(1,'2017-06-01')
insert into #temp
(
sid
,created_date
,parent_order_id
)values(1,'2017-07-01',5),(1,'2017-08-01',6)
select * from #temp
Whenever parent_order_id is null which indicates it is a new order. After that customer can add items associated to that order. so we have parent_order_id filled for these associations. But I want to know what is the first order_id for each association child order.I am looking for an output like below.
`order_id sid created_date parent_order_id original_order_id
1 1 2017-01-01 NULL 1
2 1 2017-02-01 1 1
3 1 2017-03-01 2 1
4 1 2017-04-01 3 1
5 1 2017-06-01 NULL 4
6 1 2017-07-01 5 4
7 1 2017-08-01 6 4
`
any help is appreciated. Thanks in advance.
With the following piece of code you can get results you are expecting.
;WITH cte (order_id, original_order_id)
AS
(
SELECT order_id, order_id AS original_order_id
FROM #temp WHERE parent_order_id IS NULL
UNION ALL
SELECT o.order_id AS order_id, cte.original_order_id AS original_order_id
FROM #temp AS o
JOIN cte
ON o.parent_order_id = cte.order_id
)
SELECT #temp.order_id, #temp.sid, #temp.created_date, #temp.parent_order_id, cte.original_order_id
FROM #temp
JOIN cte ON cte.order_id=#temp.order_id
ORDER BY cte.order_id
Please be aware, that there are certain limits on recursion as this for CTE. Currently it is 100 which can be pushed up to 32767.
I want to copy records from same Table. If parentID is null then I want to copy Parent and Child of that, with another parentName(I'll use replace Key word).
If it is not null then I want to copy that into same parent if same not exists in that parent only.
create table #Table(ID int primary key , Name varchar(10),ParentID int )
insert into #Table
select 1,'Suresh', -1
union
select 2,'Naresh', 1
union
select 3,'John', 1
union
select 4,'Kumar',3
union
Select 5,'Dale John',3
select * from #Table
ID Name ParentID
-------------------
1 Suresh -1
2 Naresh 1
3 John 1
4 Kumar 3
5 Dale John 3
if I select ID = 1, then all ID child should insert into same table if Name not "Suresh" and ParentID not -1.
If I select ID = 3, then ID 3 and Child should insert into same table if Name and ParentID not John & 1
Take those into Temp table and make the join between them.
IF not exists(---)
then insert into table.
I have a bunch of records in a table variable like so:
Id ProductId Rank RankCreated
1 123213 2 2011-05-02
2 123213 4 2011-05-03
3 123213 1 2011-05-03
4 155432 10 2011-05-01
5 155432 10 2011-05-02
Id is an identity column i added to my table variable (will explain why i need it in a moment). ProductId is a Product. Rank is a value which represents a product's rank at a given time. RankCreated is the time that Product was ranked.
What im trying to do:
Calculate the "movement" between each product rank, for each product. Where "movement" is defined as current - previous.
So the "computed column" would look like this:
Id ProductId Rank RankCreated Movement
1 123213 2 2011-05-02 NULL
2 123213 4 2011-05-03 2
3 123213 1 2011-05-03 -3
4 155432 10 2011-05-01 NULL
5 155432 10 2011-05-02 0
I added the Id column so i could use that to fetch the previous record.
Here's how i got the data into the temp table:
insert into #rankhistories (productid, [rank], [rankcreated])
select a.ProductId, b.[rank]
from dbo.ProductRankHistories b
inner join dbo.Products a on a.ProductId = b.ProductId
order by a.ProductId, b.RankCreated
I really can't see how i can avoid a cursor here. There are 6000+ records in that table variable, and with my cursor solution it took 5 seconds, which isn't acceptable.
Can anyone help?
DECLARE #TV TABLE
(
Id INT IDENTITY(1,1) PRIMARY KEY,
ProductId INT,
Rank INT,
RankCreated DATE
)
/*Populate *6000 rows of random data*/
INSERT INTO #TV
SELECT TOP 6000
ROW_NUMBER() OVER (ORDER BY (SELECT 0)) / 9 AS ProductId,
CRYPT_GEN_RANDOM(1) % 10 AS Rank,
GETDATE() AS RankCreated
FROM master..spt_values v1,master..spt_values v2
SELECT t1.Id,
t1.ProductId,
t1.Rank,
t1.RankCreated,
t2.Rank - t1.Rank AS Movement
FROM #TV t1
LEFT MERGE JOIN #TV t2 ON t1.Id = t2.Id+1 AND t1.ProductId=t2.ProductId
ORDER BY t1.Id
I have SQL Server 2008 with a table called ProductCategories designed like this:
Id | Name | ParentId
71 PCs NULL
32 MACs NULL
3 Keyboard 1
9 Mouse 1
5 Screen 1
11 Keyboard 2
7 Mouse 2
8 Screen 2
I would like to select from this table, and get a result set like this:
Id | Name | ParentId
71 PCs NULL
3 Keyboard 1
9 Mouse 1
5 Screen 1
32 MACs NULL
11 Keyboard 2
7 Mouse 2
8 Screen 2
I tried this, but that obviously gives me the ones with no ParentId first:
WITH Hierarchy
AS
(
SELECT
T1.Id, T1.ParentId
FROM
ProductCategories T1
WHERE
T1.parentid IS NULL OR
T1.parentid IN (SELECT id from ProductCategories WHERE parentid IS NULL)
UNION ALL
SELECT
T1.Id, T1.ParentId
FROM
ProductCategories T1
INNER JOIN
Hierarchy TH ON TH.Id = T1.ParentId
)
select *
from Hierarchy
order by parentid
Please help me, if you can :)
--
The guy who doesn't know SQL
try this:
Select Id, Name, ParentId
From ProductCategories
Order By Coalesce(ParentId, Id),
Coalesce(ParentId, 0), Name
Three Order By clauses,
Coalesce(ParentId, Id): This one groups the records by the parent, for both the parent itself and all the children of that parent
Coalesce(ParentId, 0) This groups within each set so that the one record with a null parent (the parent) sorts to the top within the group
Name, This sorts the children within the group by name
Try this
SELECT id, name, parentId
FROM categories
ORDER BY ISNULL(parentId,id), id
Btw, shouldn't first two indexes in your table be 1 and 2, not 71 and 32 ?