adding sequential number into a column - sql

I have written the code below trying to add a sequential number to a column but I am not getting my desire result.
WHERE as_at_date=(SELECT MAX(as_at_date) FROM my_table)
UNION ALL
SELECT p.customer_id, p.has_referred, (p.row_count) + 1 FROM my_table f
INNER JOIN row_num p ON p.customer_id= f.customer_id and p.row_count = 1)
--, row_num p WHERE p.customer_id = f.customer_id AND p.row_count = 4)
SELECT * FROM row_num;
I supposed to be getting something like this
customer_id
has_referred
row_count
1
true
1
2
false
2
3
true
3
However I am getting
customer_id
has_referred
row_count
1
true
1
2
false
1
3
true
1
Can I please get some help to why this is happening? Thanks in advance.

Related

Concatenate multiple rows to one big row

I have two tables in my database, with this sample data:
table 1: main
m_id eID sDate eDate
1 75 2022-12-01 NULL
table 2: details
m_id cc_id cu_id perc
1 1 1 40
1 1 2 40
1 1 3 20
Here's what I would like to achieve in SQL Server:
m_id eID sDate eDate cc_id^1 cu_id^1 perc^1 cc_id^2 cu_id^2 perc^2 cc_id^3 cu_id^3 perc^3
1 75 2022-12-01 NULL 1 1 40 1 2 40 1 3 20
So, the three rows in the 'details' table should be concatenated to the single row in the 'main' table.
I read about and tried the PIVOT Function, but I think it's not exactly what I'm looking for. To me, it seems PIVOT is using each unique value in the 'details' table as column header and then counts the number of instances of it. For example like this:
m_id eID sDate eDate 40
1 75 2022-12-01 NULL 2
So, basically using 40 as a column header and then fill its value with 2, as there are two instances of 40 in the perc column in the 'details' table.
I spent an entire day searching via Google and trying the PIVOT function without luck.
The only way I can think of it is this, (I would imagine that someone else will have a better solution!), BUT you NEED to know the values of [cu_id] ahead of time, and without knowing what the key is on Table 2, this is the best that I can do:
SELECT
Main.m_id,
Main.eID,
Main.sDate,
Main.eDate,
[Details1].[cc_id] AS [cc_id^1],
[Details1].[cu_id] AS [cu_id^1],
[Details1].[perc] AS [perc^1] ,
[Details2].[cc_id] AS [cc_id^2],
[Details2].[cu_id] AS [cu_id^2],
[Details2].[perc] AS [perc^2],
[Details3].[cc_id] AS [cc_id^3],
[Details3].[cu_id] AS [cu_id^3],
[Details3].[perc] AS [perc^3]
FROM [main] AS Main
INNER JOIN [Details] AS [Details1] ON Main.[m_id] = [Details1].[m_id]
INNER JOIN [Details] AS [Details2] ON Main.[m_id] = [Details1].[m_id]
INNER JOIN [Details] AS [Details3] ON Main.[m_id] = [Details3].[m_id]
WHERE
[Details1].[cu_id] = 1
AND
[Details2].[cu_id] = 2
AND
[Details3].[cu_id] = 3
I get the correct results, IF I know ahead of time what the values of cu_id are.
Many thanks for your help, Larnu and SWR!
#SWR unfortunately, the values for cu_id are not known ahead of time. They basically could be any integer. But thanks for your help though!
#Larnu, Thanks to you as well! I didn't post any of my pivot queries, as they got me nowhere near to the expected result. With the link to your other post, I was able to build this query.
WITH RNs AS(
SELECT h.clv_id, h.bed_id, h.wns_id, h.dvb_id, h.con_id, h.DateFrom, h.DateTo, d.kpl_id, d.kdr_id, d.dimension3, d.dimension4, d.dimension5, d.percentage
,ROW_NUMBER() OVER (PARTITION BY d.clv_id ORDER BY (SELECT NULL)) AS RN
FROM clv_hoofd h INNER JOIN clv_details d ON h.clv_id = d.clv_id
WHERE h.clv_id = 1094)
SELECT clv_id, bed_id, wns_id, dvb_id, con_id, DateFrom, DateTo,
CASE RN WHEN 1 THEN kpl_id END AS 'kpl^1',
CASE RN WHEN 1 THEN kdr_id END AS 'kdr^1',
CASE RN WHEN 1 THEN dimension3 END AS 'dim3^1',
CASE RN WHEN 1 THEN dimension4 END AS 'dim4^1',
CASE RN WHEN 1 THEN dimension5 END AS 'dim5^1',
CASE RN WHEN 1 THEN percentage END AS 'perc^1',
CASE RN WHEN 2 THEN kpl_id END AS 'kpl^2',
CASE RN WHEN 2 THEN kdr_id END AS 'kdr^2',
CASE RN WHEN 2 THEN dimension3 END AS 'dim3^2',
CASE RN WHEN 2 THEN dimension4 END AS 'dim4^2',
CASE RN WHEN 2 THEN dimension5 END AS 'dim5^2',
CASE RN WHEN 2 THEN percentage END AS 'perc^2',
CASE RN WHEN 3 THEN kpl_id END AS 'kpl^3',
CASE RN WHEN 3 THEN kdr_id END AS 'kdr^3',
CASE RN WHEN 3 THEN dimension3 END AS 'dim3^3',
CASE RN WHEN 3 THEN dimension4 END AS 'dim4^3',
CASE RN WHEN 3 THEN dimension5 END AS 'dim5^3',
CASE RN WHEN 3 THEN percentage END AS 'perc^3',
CASE RN WHEN 4 THEN kpl_id END AS 'kpl^4',
CASE RN WHEN 4 THEN kdr_id END AS 'kdr^4',
CASE RN WHEN 4 THEN dimension3 END AS 'dim3^4',
CASE RN WHEN 4 THEN dimension4 END AS 'dim4^4',
CASE RN WHEN 4 THEN dimension5 END AS 'dim5^4',
CASE RN WHEN 4 THEN percentage END AS 'perc^4',
CASE RN WHEN 5 THEN kpl_id END AS 'kpl^5',
CASE RN WHEN 5 THEN kdr_id END AS 'kdr^5',
CASE RN WHEN 5 THEN dimension3 END AS 'dim3^5',
CASE RN WHEN 5 THEN dimension4 END AS 'dim4^5',
CASE RN WHEN 5 THEN dimension5 END AS 'dim5^5',
CASE RN WHEN 5 THEN percentage END AS 'perc^5',
CASE RN WHEN 6 THEN kpl_id END AS 'kpl^6',
CASE RN WHEN 6 THEN kdr_id END AS 'kdr^6',
CASE RN WHEN 6 THEN dimension3 END AS 'dim3^6',
CASE RN WHEN 6 THEN dimension4 END AS 'dim4^6',
CASE RN WHEN 6 THEN dimension5 END AS 'dim5^6',
CASE RN WHEN 6 THEN percentage END AS 'perc^6'
FROM RNs R
This returns six rows, doing it like this:
kpl_id^1 kdr_id^1 dimension3^1 dimension4^1 dimension5^1 percentage^1 kpl_id^2 kdr_id^2 dimension3^2 dimension4^2 dimension5^2 percentage^2
2 1 00000 01 NVT 50.00 NULL NULL NULL NULL NULL NULL
NULL NULL NULL NULL NULL NULL 1 1 00000 02 NVT 10.00
...
This query comes from my real world database, hence the different names for tables and columns.
Thanks in advance!

SUM the COUNT results from a database table with two different value

I'd like to count total events, which can have two different values, and I could not figure out how to merge them together. My query is the following:
SELECT TOP(20)
[MatchEvents].[PlayerID], [MatchEvents].[EventType],
COUNT([MatchEvents].[ID]) AS [TOTAL]
FROM
[MatchEvents]
INNER JOIN
[Match] ON [MatchEvents].[MatchID] = [Match].[ID]
AND [Match].[Season] = 1
WHERE
([MatchEvents].[EventType] = 0 OR [MatchEvents].[EventType] = 1)
GROUP BY
[MatchEvents].[PlayerID], [MatchEvents].[EventType]
ORDER BY
[TOTAL] ESC
Current output:
PlayerID
EventType
Total
1
0
8
1
1
3
2
0
8
2
1
3
3
0
8
3
1
3
Expected output:
PlayerID
Total
1
11
2
11
3
11
How could I merge my current results further?
Thanks!
From your expected results it appears you just need to remove grouping by EventType
I would suggest the following:
select top(20) me.PlayerID, Count(*) as Total
from MatchEvents me
join [Match] m on m.Id = me.MatchId and m.Season = 1
where me.EventType in (0, 1)
group by me.PlayerID
order by Total desc;

Identify same amounts over different users

Consider the following table Orders:
OrderID Name Amount
-----------------------
1 A 100
2 A 5
3 B 32
4 C 4000
5 D 701
6 E 32
7 F 200
8 G 100
9 H 12
10 I 17
11 J 100
12 J 100
13 J 11
14 A 5
I need to identify, for each unique 'Amount', if there are 2 or more users that have ordered that exact amount, and then list the details of those orders. So the desired output would be:
OrderID Name Amount
---------------------
1 A 100
8 G 100
11 J 100
12 J 100
3 B 32
6 E 32
please note that user A has ordered 2 x an order of 5 (order 2 and 14) but this shouldn't be in the output as it is within the same user. Only if another user would have made a order of 5, it should be in the output.
Can anyone help me out?
I would just use exists:
select o.*
from orders o
where exists (select 1
from orders o2
where o2.amount = o.amount and o2.name <> o.name
);
You can do :
select t.*
from table t
where exists (select 1 from table t1 where t1.amount = t.amount and t1.name <> t.name);
If you want only selected field then
SELECT Amount,name,
count(*) AS c
FROM TABLE
GROUP BY Amount, name
HAVING c > 1
ORDER BY c DESC
if you want full row
select * from table where Amount in (
select Amount, name from table
group by Amount, name having count(*) > 1)

sql server count distinct value of a field

I have 2 tables : Contents and Packs
In Content columns are like this:
Id Name IsPerishable IsSpecial IsDanger
----------------------------------------------------------
1 Paper False False False
3 Fruit True False False
5 NewsPaper False True False
6 Radioactive False False True
7 Foods True False False
In Packs columns are like this:
Id From To ContentId
---------------------------------------
1 ABZ ATL 3
2 ANU ATL 5
3 BAQ ATL 7
4 BTS BAQ 6
5 FRL BAQ 5
Now I want a result that groups every 'To' then shows separate value of IsPerishable / IsSpecial / IsDanger
like this:
To Perishable Special Danger
-----------------------------------------------
ATL 2 1 0
BAQ 0 1 1
I try use some query but none of them has worked correctly:
select Name,
case
when IsSpecial = 1 then count(IsSpecial)
when IsPerishable = 1 then count(IsPerishable)
when IsDanger = 1 then count(IsDanger)
end as 'Content'
from Contents
group by IsSpecial , IsPerishable , IsDanger
select To,count(DISTINCt Id) as 'Count'
FROM Packs
GROUP BY To
try this
Select To,
(Select count(*) from Content c where c.Id= p.Id and c.IsSpecial=1) as Special,
(Select count(*) from Content c where c.Id= p.Id and c.Isperishable=1) as Perishable,
(Select count(*) from Content c where c.Id= p.Id and c.Isperishable=1) as Danger
from
pack p
group by To
SELECT P.To, SUM(Perishable), SUM(Special),SUM(Danger) FROM
(
SELECT Id,
CASE IsPerishable WHEN true THEN 1 ELSE 0 END AS Perishable,
CASE IsSpecial WHEN true then 1 ELSE 0 END AS Special,
CASE IsDanger WHEN true then 1 ELSE 0 END AS Danger
FROM Contents
) C
Right Join Packs P
on P.ContentId=C.Id
Group BY P.to

Copying existing rows in a table

How do I go about doing the following?
I am using the following query to get a specific users tab ids:
select id
from intranet.dbo.tabs
where cms_initials = #user
order by id asc
which might return the following ids
4
5
6
7
I now want to insert the rows from the following query:
select tabs_id, widgets_id, sort_column, sort_row
from intranet.dbo.columns c
inner join intranet.dbo.tabs t on c.tabs_id = t.id
where t.is_default = 1
But use the ids from the first query to replace the tab ids
so if the second query originally returns tabs_id's as
0
0
0
0
1
1
1
2
2
2
3
3
I should end up with
0
0
0
0
1
1
1
2
2
2
3
3
4
4
4
4
5
5
5
6
6
6
7
7
Is this possible with sql server 2005 without using stored procedures?
So far I have
insert into intranet.dbo.columns ( tabs_id, widgets_id, sort_column, sort_row )
select tabs_id, widgets_id, sort_column, sort_row
from intranet.dbo.columns c
inner join intranet.dbo.tabs t on c.tabs_id = t.id
where t.is_default = 1
But this just copies everything as is, I need to do that, but replace the ids in the copied rows.
This solution uses common table expressions and ranking functions. A and B are your original queries ranked by tab order. A and B are then joined by tab ranking and inserted.
USE intranet
;WITH A AS
(
SELECT ROW_NUMBER() OVER (ORDER BY id) AS tab_ranking
, id
FROM dbo.tabs
WHERE cms_initials = #user
),
B AS
(
SELECT DENSE_RANK() OVER (ORDER BY tabs_id) AS tab_sequence
, tabs_id, widgets_id, sort_column, sort_row
FROM dbo.columns
WHERE tabs_id IN (SELECT t.id FROM dbo.tabs t WHERE t.is_default = 1)
)
INSERT INTO dbo.columns (tabs_id, widgets_id, sort_column, sort_row)
SELECT a.id, b.widgets_id, b.sort_column, b.sort_row
FROM A
INNER JOIN B ON B.tab_ranking = A.tab_ranking