I am stuck with an issue here.
I have the following table
ID TX_NAME DT_DATE ID_SUCCESSOR
1 Task 1 Jan/01/2012 2
2 Task 2 Jan/02/2012 3
3 Task 3 Jan/01/2012
My objective is to create an SQL statement which brings me TX_NAME which its DT_DATE is later and its ID_SUCCESSOR.
For example, ID = 2 is the one I am looking for as it happens after its successor (ID = 3)
Is it possible in a single query?
Thanks
select t.* from
TestTable t
inner join TestTable t2 on t2.id = t.ID_SUCCESSOR
where t.DT_DATE > t2.DT_DATE
Not tested, but ought to be ok :)
SELECT TX_NAME
from MyTable T1
where DT_DATE > (
SELECT DT_DATE
from MyTable T2
where T1.ID_SUCCESSOR = T2.ID
)
Related
I'm needing to verify a source system with a destination system and ensure the values are matching between them. The problem is the source system is a total mess and is proving hard to validate.
I've got the following sample data where they should all be OK, but they're showing as ERROR. Does anyone know a way of doing a comparison that would result as an OK for all for the below?
CREATE TABLE #testdata (
ID INT
,ValueSource VARCHAR(800)
,ValueDestination VARCHAR(800)
,Value_Varchar_Check AS (
CASE
WHEN coalesce(ValueSource, '0') = coalesce(ValueDestination, '0')
THEN 'OK'
ELSE 'ERROR'
END
)
)
INSERT INTO #testdata (
ID
,ValueSource
,ValueDestination
)
SELECT 1
,'hepatitis c,other (specify)' 'hepatitis c, other (specify)'
UNION ALL
SELECT 2
,'lung problems / asthma,lung problems / asthma'
,'lung problems / asthma'
UNION ALL
SELECT 3
,'lung problems / asthma,diabetes'
,'diabetes, lung problems / asthma'
UNION ALL
SELECT 4
,'seizures/epilepsy,hepatitis c,seizures/epilepsy'
,'hepatitis c, seizures/epilepsy'
I don't think you can write this as a generated column as it is quite a tricky thing to compute. If you are using SQL Server 2016 or later, you can use STRING_SPLIT to convert the ValueSource and ValueDestination values into tables and then sort them alphabetically using a query like this:
SELECT DISTINCT ID, TRIM(value) AS value,
DENSE_RANK() OVER (PARTITION BY ID ORDER BY TRIM(value)) AS rn
FROM testdata
CROSS APPLY STRING_SPLIT(ValueSource, ',')
For ValueSource, this produces:
ID value rn
1 hepatitis c 1
1 other (specify) 2
2 lung problems / asthma 1
3 diabetes 1
3 lung problems / asthma 2
4 hepatitis c 1
4 seizures/epilepsy 2
You can then FULL OUTER JOIN those two tables on ID, value and rn, and detect an error when there are null values from either side (since that implies that the values for a given ID and rn don't match):
WITH t1 AS (
SELECT DISTINCT ID, TRIM(value) AS value,
DENSE_RANK() OVER (PARTITION BY ID ORDER BY TRIM(value)) AS rn
FROM testdata
CROSS APPLY STRING_SPLIT(ValueSource, ',')
),
t2 AS (
SELECT DISTINCT ID, TRIM(value) AS value,
DENSE_RANK() OVER (PARTITION BY ID ORDER BY TRIM(value)) AS rn
FROM testdata
CROSS APPLY STRING_SPLIT(ValueDestination, ',')
)
SELECT COALESCE(t1.ID, t2.ID) AS ID,
CASE WHEN COUNT(CASE WHEN t1.value IS NULL OR t2.value IS NULL THEN 1 END) > 0 THEN 'Error'
ELSE 'OK'
END AS Status
FROM t1
FULL OUTER JOIN t2 ON t2.ID = t1.ID AND t2.rn = t1.rn AND t2.value = t1.value
GROUP BY COALESCE(t1.ID, t2.ID)
Output (for your sample data):
ID Status
1 OK
2 OK
3 OK
4 OK
Demo on SQLFiddle
You can then use the entire query above as a CTE (call it t3) to update your original table:
UPDATE t
SET t.Value_Varchar_Check = t3.Status
FROM testdata t
JOIN t3 ON t.ID = t3.ID
Output:
ID ValueSource ValueDestination Value_Varchar_Check
1 hepatitis c,other (specify) hepatitis c, other (specify) OK
2 lung problems / asthma,lung problems / asthma lung problems / asthma OK
3 lung problems / asthma,diabetes diabetes, lung problems / asthma OK
4 seizures/epilepsy,hepatitis c,seizures/epilepsy hepatitis c, seizures/epilepsy OK
Demo on SQLFiddle
Following are the two tables in SQL Server: TABLE_A and TABLE_B
I need to get the output as follows:
Get IDs from TABLE_A where Exist = 0
We would get 100, 101 & 102
Now, among 100, 101 & 102, no other rows (in the same table) with the same ID value should have Exist = 1
Hence, 100 can't be selected as it has Exist = 1 in the 2nd row.
So, only 101 & 102 remain
With the remaining ID values (101 & 102), check against the ID column in TABLE_B where 'Exist' column value should not be equal to '1' in any of the rows
In TABLE_B, 4th row has Exist = 1 for 102. So, that can't be selected
We have only 101 now. This is required output and that should be selected.
Could you let me know how to write the simplest query to achieve this please? Let me know if the question needs to be improved.
You can use exists & not exists :
with t as (
select t1.*
from t1
where exists (select 1 from t1 t11 where t11.id = t1.id and t11.exists = 0) and
not exists (select 1 from t1 t11 where t11.id = t1.id and t11.exists = 1)
)
select t.*
from t
where not exists (select 1 from t2 where t.id = t2.id and t2.exists = 1);
Try:
SELECT
ID,
SUM(CAST(Exist AS int)) AS [Exists]
FROM
TABLE_A
GROUP BY ID
HAVING SUM(CAST(Exist AS bit)) = 0
will give you the answer to the first part. You can then JOIN this to a similar query for TABLE_B. That is a "simple" way to show how this works. You can write more complex queries as that from #Yogest Sharma
Like #Peter Smith mentioned, you can use the aggregate function SUM. Note that you would need a cast since you cannot use the aggregate function on a field that has a BIT datatype
;WITH CTE AS
(
SELECT ID, SUM(CAST(Exist AS INT)) AS AggExist FROM TABLE_A GROUP BY ID
UNION
SELECT ID, SUM(CAST(Exist AS INT)) As AggExist FROM TABLE_B GROUP BY ID
)
SELECT ID, SUM(AggExist) FROM CTE GROUP BY ID
HAVING SUM(AggExist) = 0
Here is the demo
for example, I have 2 tables
resto1
day 1 = 1 2 3 4
resto2
day 1 = 5 6 7 8
I wanted to add the values of the first two columns that have the same date the result would be:
day_1_earned = 6 8 10 12
please help
assuming both the tables have a date column, let say named dt_col you can use below query to achieve the required result
select t1.column1+t2.column2 added_values from
table1 t1,table2 t2
where t1.dt_col = t2.dt_col;
SELECT T1.Column1 + T2.Column As TotalColumn
From T1, T2 WHERE T1.Date= T2.Date
SELECT Cr_date, SUM(Column1) Column1, SUM(Column2) Column2
FROM
(
SELECT Cr_Date,Column1,Column2 FROM #T1
UNION
SELECT Cr_Date,Column1,Column2 FROM #T2
) as res
GROUP BY Cr_Date
SQL Server 2008-12
I have table:
InteractionKey char(18)
dEventTime datetime
SeqNo int
cEventData1
There will be multiple entries per InteractionKey - dEventTime only goes out to the Seconds and SeqNo is incremented if two entries occur on the same second.
What I need to do is select the First and Second record BEFORE the record where
cEventData1 = 'Disconnect'
The final product will give me a count of occurrences grouped by cEventData1.
I am currently using a cursor (will update with cursor source momentarily) I would like to use a CTE - but I really struggle with understanding them...
Any ideas would be appreciated!
Update with Data Sample
INTERACTIONKEY dEventTime SeqNo cEventData1
100186322420130722 2013-07-22 11:50:49.000 1 EnterPassword
100186322420130722 2013-07-22 11:50:49.000 2 CheckPassword
100186322420130722 2013-07-22 11:50:49.000 3 Attendant Disconnect
The result of the query would ideally tell me - : NOTE The Action column here can be simply 'Attendant Disconnect' as Action
cEventData1 Action Count
CheckPassword Attendant Disconnect 1
Here is the query I ended up going with based upon the below answer
SELECT DISTINCT t1.InteractionKey,
DisconnectTime = t1.dEventTime,
PreviousEventTime = t2.dEventTime,
PreviousEvent = t2.cEventData1,
t2.SeqNo
FROM IVRHistory t1
OUTER APPLY
( SELECT TOP 1 t2.dEventTime, t2.SeqNo, t2.cEventData1
FROM IVRHistory t2
WHERE t1.InteractionKey = t2.InteractionKey
AND t1.dEventTime >= t2.dEventTime
AND t1.SeqNo > t2.SeqNo
AND t2.cEventData1 <> 'Attendant Disconnect'
ORDER BY t2.dEventTime DESC, t2.SeqNo DESC
) t2
WHERE t1.cEventData1 = 'Attendant Disconnect'
I would approach this using APPLY:
SELECT t1.InteractionKey,
DisconnectTime = t1.dEventTime,
PreviousEventTime = t2.dEventTime,
PreviousEvent = t2.cEventData1,
t2.SeqNo
FROM T t1
OUTER APPLY
( SELECT TOP 2 t2.dEventTime, t2.SeqNo, t2.cEventData1
FROM T t2
WHERE t1.InteractionKey = t2.InteractionKey
AND t1.dEventTime > t2.dEventTime
ORDER BY t2.dEventTime DESC
) t2
WHERE t1.cEventData1 = 'Disconnect';
This will give you the two records immediately preceeding the disconnect event. If you need more than two records if there are duplicate times you can use TOP 2 WITH TIES.
Without your sample input and output I am guessing a bit, but from what you have said your final aggregate would be:
SELECT t2.cEventData1,
Occurances = COUNT(*)
FROM T t1
OUTER APPLY
( SELECT TOP 2 t2.dEventTime, t2.SeqNo, t2.cEventData1
FROM T t2
WHERE t1.InteractionKey = t2.InteractionKey
AND t1.dEventTime > t2.dEventTime
ORDER BY t2.dEventTime DESC
) t2
WHERE t1.cEventData1 = 'Disconnect'
GROUP BY t2.cEventData1;
Probably it has been asked before but I cannot find an answer.
Table Data has two columns:
Source Dest
1 2
1 2
2 1
3 1
I trying to come up with a MS Access 2003 SQL query that will return:
1 2
3 1
But all to no avail. Please help!
UPDATE: exactly, I'm trying to exclude 2,1 because 1,2 already included. I need only unique combinations where sequence doesn't matter.
For Ms Access you can try
SELECT DISTINCT
*
FROM Table1 tM
WHERE NOT EXISTS(SELECT 1 FROM Table1 t WHERE tM.Source = t.Dest AND tM.Dest = t.Source AND tm.Source > t.Source)
EDIT:
Example with table Data, which is the same...
SELECT DISTINCT
*
FROM Data tM
WHERE NOT EXISTS(SELECT 1 FROM Data t WHERE tM.Source = t.Dest AND tM.Dest = t.Source AND tm.Source > t.Source)
or (Nice and Access Formatted...)
SELECT DISTINCT *
FROM Data AS tM
WHERE (((Exists (SELECT 1 FROM Data t WHERE tM.Source = t.Dest AND tM.Dest = t.Source AND tm.Source > t.Source))=False));
your question is asked incorrectly. "unique combinations" are all of your records. but i think you mean one line per each Source. so it is:
SELECT *
FROM tab t1
WHERE t1.Dest IN
(
SELECT TOP 1 DISTINCT t2.Dest
FROM tab t2
WHERE t1.Source = t2.Source
)
SELECT t1.* FROM
(SELECT
LEAST(Source, Dest) AS min_val,
GREATEST(Source, Dest) AS max_val
FROM table_name) AS t1
GROUP BY t1.min_val, t1.max_val
Will return
1, 2
1, 3
in MySQL.
To eliminate duplicates, "select distinct" is easier than "group by":
select distinct source,dest from data;
EDIT: I see now that you're trying to get unique combinations (don't include both 1,2 and 2,1). You can do that like:
select distinct source,dest from data
minus
select dest,source from data where source < dest
The "minus" flips the order around and eliminates cases where you already have a match; the "where source < dest" keeps you from removing both (1,2) and (2,1)
Use this query :
SELECT distinct * from tabval ;