Get only one Value Per Date In SQL Script - sql-server

I have a table with the columns Lkup_Value and Report_Date. Based on the below table I need to write the SQL Script like, if for the same Report_Date there are two Lkup_values values, then need to take only one Lkup_Value.
Lkup_Value | Report_Date
-------------------+------------------------------
MMM |2022-07-11
MMM-IR |2022-07-11
MMM-IR |2022-07-04
MMM |2022-07-04
CCC |2022-01-26
CCC |2022-01-03
OutPut:-
Lkup_Value | Report_Date
-------------------+------------------------------
MMM |2022-07-11
MMM |2022-07-11
MMM |2022-07-04
MMM |2022-07-04
CCC |2022-01-26
CCC |2022-01-03
For example, for the Report_Date “2022-07-11” there are two Lkup_Values i.e. “MMM” and “MMM-IR” then, in this scenario I need to take only "MMM". Overall If a day (Report_Date) contains the Lkup_Values “MMM” then irrespective of another values I need to take only "MMM".

WITH CTE(Lkup_Value, Report_Date )
AS
(
SELECT 'MMM' , '2022-07-11' UNION ALL
SELECT'MMM-IR' , '2022-07-11' UNION ALL
SELECT'MMM-IR' , '2022-07-04' UNION ALL
SELECT'MMM' , '2022-07-04' UNION ALL
SELECT 'CCC' , '2022-01-26' UNION ALL
SELECT'CCC' , '2022-01-03' UNION ALL
SELECT 'MMM','2022-01-03'
)
SELECT TOP 1 WITH TIES X.Lkup_Value,X.Report_Date
FROM CTE AS X
ORDER BY ROW_NUMBER()OVER(PARTITION BY X.Report_Date ORDER BY CASE WHEN X.Lkup_Value='MMM'THEN 1 ELSE 2 END ASC)

Related

How to pivot wider these dataset

My test dataset
IdCx FecCx OrderId Value
1234 2022-08-15 1 07:50
1234 2022-08-15 2 08:00
1234 2022-08-15 3 08:24
5678 2022-08-16 1 14:45
5678 2022-08-16 3 15:30
I require to pivot wider based on OrderId and Value
My expected result will look like (I do need the NULL in Val2)
IdCx FecCx Val1 Val2 Val3
1234 2022-08-15 07:50 08:00 08:24
5678 2022-08-16 14:45 NULL 15:30
My first approach has been with CASE but resulting dataset will not coalesce rows, leaving a lot of undesired nulls
My dbFiddle
You simply need to aggregate - this collapses your NULL values into one row per group:
select idCx, FecCx
,max(case when OrderId = 1 then Value end) as Val1
,max(case when OrderId = 2 then Value end) as Val2
,max(case when OrderId = 3 then Value end) as Val3
from dbo.fact1
group by idCx, FecCx;
See modified Fiddle
Just in case ORderID is not sequential, we use the window function row_number() over() in concert with a PIVOT
Example or dbFiddle
Select *
From (
Select IDcx
,FecCx
,Item = concat('Val',row_number() over (partition by idcx,FecCx order by OrderID) )
,Value
From fact1
) src
Pivot ( max(Value) for Item in ([Val1],[Val2],[Val3])) pvt

Select records in the previous 12 hour window

I have table in below structure,
Id Name Created_Date
1 AAA 10/20/2019 3:00:00
2 BBB 10/20/2019 15:00:00
3 CCC 10/21/2019 4:00:00
4 DDD 10/21/2019 18:00:00
I need single query that needs to return based on current date and time, For example:
Case 1: Current Date is 10/21/2019 and time is in AM, It needs to return Previous date (10/20/2019), Second half(10/20/2019 12:00:01 to 10/20/2019 23:59:59).
In our case, Record "BBB" needs to be return.
Case 2: Current Date is 10/21/2019 and time is in PM, It needs to return current date (10/21/2019), First half(10/21/2019 00:00:01 to 10/21/2019 11:59:59).
In our case, Record "CCC" needs to be return.
Try this,
DECLARE #Temp_Table TABLE
(
Id INT,Name VARCHAR(10),Created_Date DATETIME
)
INSERT INTO #Temp_Table
SELECT 1,'AAA','10/20/2019 3:00:00 ' UNION ALL
SELECT 2,'BBB','10/20/2019 15:00:00' UNION ALL
SELECT 3,'CCC','10/21/2019 4:00:00 ' UNION ALL
SELECT 4,'DDD','10/21/2019 18:00:00'
DECLARE #DATE_TIME DATETIME='10/21/2019 18:00:00'
SELECT *
FROM #Temp_Table
WHERE Created_Date BETWEEN IIF(DATEPART(HOUR,#DATE_TIME) >12,CAST(CAST(#DATE_TIME AS DATE) AS DATETIME),DATEADD(HOUR,12,DATEADD(DAY,-1,CAST(CAST(#DATE_TIME AS DATE) AS DATETIME))))
AND IIF(DATEPART(HOUR,#DATE_TIME) >12,DATEADD(HOUR,12,CAST(CAST(#DATE_TIME AS DATE) AS DATETIME)),CAST(CAST(#DATE_TIME AS DATE) AS DATETIME))
Try This
SELECT ID,Name, Created_Date
FROM
(
SELECT *, CASE WHEN DATEDIFF(Hour, GETDATE() ,Created_Date) < 0 AND DATEDIFF(Hour, GETDATE() ,Created_Date) >= -12 THEN Created_Date ELSE NULL END AS ComputedColumn
FROM Tbl
) X WHERE ComputedColumn IS NOT NULL
SQL FIDDLE

get unique records existing only once per day in a date range

I have a case where I want to extract the device ids (DIDs) that exist only and only once for each day in a certain period. I have tried different methods and partitions but I seem to only be able to get that data individually per day (where date = X, but I need a query where I can put where date between X & Y)
Example, this is the data:
DID date
A 2019-01-01
A 2019-01-01
A 2019-01-02
A 2019-01-03
B 2019-01-01
B 2019-01-02
B 2019-01-03
C 2019-01-01
C 2019-01-02
C 2019-01-02
C 2019-01-03
D 2019-01-01
D 2019-01-02
D 2019-01-03
The query should return only B & D(because B & D exists once in each day from 01 to 03)
I also wish to get the count, which would be 2 in this case
thanks!
You want the devices to exist only once on each day of the period, so if you group by did you need to return the dids that have count(date) and count(distinct date) equal to the number of days of that period:
select did
from tablename
where date between cast('2019-01-01' as date) and cast('2019-01-03' as date)
group by did
having
count(distinct date) = cast('2019-01-03' as date) - cast('2019-01-01' as date) + 1
and
count(date) = cast('2019-01-03' as date) - cast('2019-01-01' as date) + 1
See the demo.
Or:
select t.did
from (
select did, date
from tablename
where date between cast('2019-01-01' as date) and cast('2019-01-03' as date)
group by did, date
having count(*) = 1
)t
group by t.did
having count(*) = cast('2019-01-03' as date) - cast('2019-01-01' as date) + 1
See the demo.
Result:
| did |
| --- |
| B |
| D |
One option would be to aggregate by DID and assert that the total count is equal to the count of distinct dates. If this assertion passes, it means that a given DID has only distinct dates present.
SELECT DID
FROM yourTable
GROUP BY DID
HAVING COUNT(date) = COUNT(DISTINCT date);
Demo
If you want to get the total count of matching DID, then you could subquery the above and take COUNT(*). Or, if you wanted to use the same query you might try:
SELECT DID, COUNT(*) OVER () AS total_cnt
FROM yourTable
GROUP BY DID
HAVING COUNT(date) = COUNT(DISTINCT date);

Row to Column Group by ID SQL Server

I have a table like this:
id name date
-------------------
1 Adam 2018-10-01
1 Adam 2018-08-01
2 Eve 2018-07-01
2 Eve 2018-05-01
I want it to become like this:
id name firstdate lastdate
--------------------------------
1 Adam 2018-08-01 2018-10-01
2 Eve 2018-05-01 2018-07-01
I tried to use this query but it failed:
SELECT * FROM View_MySource
PIVOT (
MIN(mydate)
FOR id IN ([firstdate], [lastdate])
) piv
I am new to pivot, can someone help me?
I might even avoid using PIVOT in this case:
SELECT
id,
name,
MIN(date) AS firstdate,
MAX(date) AS maxdate
FROM View_MySource
GROUP BY
id,
name;
This has actually nothing to do with pivoting data. All you want to do is get the minimum and maximum date per ID; a simple aggregation:
select id, name, min(date) as firstdate, max(date) as lastdate
from view_mysource
group by id, name
order by id;

sql print duplicate value only one time

i have a table like the following
bill_id sonvinid tid date brandname
1000109201701 13413 1 2015-10-03 00:00:00.000 QED - TM
1000109201701 13741 1 2015-10-13 00:00:00.000 QED - TM
1000109201702 14258 1 2015-11-05 00:00:00.000 QED - TM
now i want to run a query in which bill_id should not repeat, and repeated column with same bill_id should be shown as null
bill_id sonvinid tid date brandname
1000109201701 13413 1 2015-10-03 00:00:00.000 QED - TM
13741 1 2015-10-13 00:00:00.000 QED - TM
1000109201702 14258 1 2015-11-05 00:00:00.000 QED - TM
i know i can't use distinct here
then, what query will be the best to run this type of select command?
SELECT CASE WHEN row_num = 1 THEN bill_id ELSE NULL END AS bill_id
, sonvinid
, tid
, date
, brandname
FROM
( SELECT bill_id
, ROW_NUMBER() OVER (PARTITION BY bill_id ORDER BY date ASC) row_num
, sonvinid
, tid
, date
, brandname
FROM table1
) a;
Anyway I agree with the Sean's comment, that this is supposed to be done on UI side

Resources