The following query:
SELECT T1.REPORTED_NAME, STRING_AGG(CAST(T1.ENTRY AS NVARCHAR(MAX)),',') AS Average_Str
FROM Table1 T1
INNER JOIN Table2 T2 ON T1.ID = T2.ProdID
WHERE T1.ENTRY like '%[A-Za-z]%'
GROUP BY T1.REPORTED_NAME
ORDER BY T1.REPORTED_NAME
Returns:
REPORTED_NAME Average_Str
Report_1 Failed,Failed,Failed,Failed,Failed,
Report_2 Passed,Passed,Passed
I would like my final output to have only unique value as below
REPORTED_NAME Average_Str
Report_1 Failed
Report_2 Passed
Thank you in advance for your help
You can go for first getting unique values and then applying string aggregate like below:
;WITH CTE_UniqueValues
(
SELECT Reported_Name, Entry, MAX(ID) AS ID
FROM Table1
GROUP BY Reported_Name, Entry
)
SELECT T1.REPORTED_NAME, STRING_AGG(CAST(T1.ENTRY AS NVARCHAR(MAX)),',') AS Average_Str
FROM CTE_UniqueValues T1
INNER JOIN Table2 T2 ON T1.ID = T2.ProdID
WHERE T1.ENTRY like '%[A-Za-z]%'
GROUP BY T1.REPORTED_NAME
ORDER BY T1.REPORTED_NAME
Related
I have about 10 tables that I make one big nested tables by rounds with the following query:
R1 AS(
SELECT ANY_VALUE(Table1).*, ARRAY_AGG(( SELECT AS STRUCT Table2.* EXCEPT(ID))) AS Table2
FROM Table1 LEFT JOIN Table2 USING(ID)
GROUP BY Table1.ID),
R2 AS(
SELECT ANY_VALUE(R1).*, ARRAY_AGG(( SELECT AS STRUCT Table3.* EXCEPT(ID))) AS Table3
FROM R1 LEFT JOIN Table3 USING(ID)
GROUP BY R1.ID),
...
SELECT ANY_VALUE(R9).*, ARRAY_AGG(( SELECT AS STRUCT Table10.* EXCEPT(ID))) AS Table10
FROM R9 LEFT JOIN Table10 USING(ID)
The thing is that for example in my first table I can have two records with the same ID but some other fields will be different and I want to consider them as two distinct records and thus group by all the fields of the table while I join.
Then I want to do the same with all the "sub-table" (the R tables in the query), so I will able to group by all the fields of the nested tables.
How can I do it easily ?
I tried GROUP BY Table1.* but it doesn't work...
Thank you in advance
Try to_json_string:
...
FROM Table1 t1
...
GROUP BY to_json_string(t1)
You seem to want something like this:
select *
from table1 t1 left join
(select t2.*
from table2 t2
where true
qualify row_number() over (partition by t2.id order by t2.id) = 0
) t2
using (id)
This uses qualify instead of group by to fetch one row.
If you don't want all rows from from table1, you can whittle them down as well:
select *
from (select t1.*
from table1 t1
where true
qualify row_number() over (partition by id, col1, col2 order by id) = 1
) t1 left join
(select t2.*
from table2 t2
where true
qualify row_number() over (partition by t2.id order by t2.id) = 0
) t2
using (id)
How to Group By all fields ...?
I tried GROUP BY Table1.* but it doesn't work...
Consider below example
SELECT ANY_VALUE(t1).*,
ARRAY_AGG(( SELECT AS STRUCT t2.* EXCEPT(ID))) AS Table2
FROM Table1 t1 LEFT JOIN Table2 t2 USING(ID)
GROUP BY FORMAT('%t', t1)
I'm new to mssql .Here am trying to get values from database by joining three tables .
Table 1:
Table 2 :
Here the image there is a possibility for a single user can have multiple image id form this I need to take any one of the image.
Table 3 :
Here am joining the Table 1 and Table 2 by using H_ID
and Table 2 and Table 3 by using IMG_ID.
What I want to do is Need to get all the colum values from Table 1 and Table 2 But the first URL from the Table 3.
In this case an employee has multiple images in the Table I need to take the 1 URL.
Result should be like this :
Query :
SELECT T1.H_ID AS 'ID',
T1.NAME,
T1.ROLE,
T2.SALARY,
T3.IMAGE
FROM TABLE1 T1
JOIN TABLE2 T2
ON T1.H_ID T2.H_ID
JOIN TABLE3 T3
ON T3.IMG_ID = T2.IMG_ID
WHERE T1.STATUS = 'ACTIVE'
Now this query returns 3 rows for the id H_ID = 1001 but It should be a single row.
Can anyone help me to fix this .
use row_number()
with cte as
(SELECT T1.H_ID AS 'ID',T1.NAME,T1.ROLE,T2.SALARY,T3.IMAGE
,row_number() over(partition by T2.img_id order by T3.id) rn
FROM TABLE1 T1
JOIN TABLE2 T2
ON T1.H_ID T2.H_ID
JOIN TABLE3 T3
ON T3.IMG_ID = T2.IMG_ID WHERE T1.STATUS = 'ACTIVE'
) select * from cte where rn=1
After you comments it seems you need subquery
select T1.*,T2.sal,a.url
FROM TABLE1 T1
JOIN TABLE2 T2
ON T1.H_ID T2.H_ID
left join ( select min(id),img_id,url from table3 group by img_id,url) a
on T2.IMG_ID= a.img_id
WHERE T1.STATUS = 'ACTIVE'
I think, You can simply use OUTER APPLY and TOP 1 for that
SELECT T1.H_ID AS 'ID',
T1.NAME,
T1.ROLE,
T2.SALARY,
T3.IMAGE
FROM TABLE1 T1
JOIN TABLE2 T2 ON T1.H_ID T2.H_ID
OUTER APPLY(SELECT TOP 1 T3.IMAGE
FROM TABLE3 T3 WHERE T3.IMG_ID = T2.IMG_ID
--ORDER BY <column_name> --to take top 1 value in specific order
) T3
WHERE T1.STATUS = 'ACTIVE'
In the table1 I have 1421144 rows and table2 has 1421134 rows.
I tried this query, but I don't get any rows returned.
select table1.ID
from table1
where ID not in (select ID from table2)
I have also used this query:
select ID from table1
except
select ID from table2
But I don't get any rows. Please help me, if the table1 has duplicates how can I get those duplicates?
Assuming ids are unique, you can use full outer join in either database:
select coalesce(t1.id, t2.id) as id,
(case when t1.id is null then 'T2 only' else 'T1 only' end)
from t1 full outer join
t2
on t1.id = t2.id
where t1.id is null or t2.id is null;
It is quite possible that the two tables have the same sets of ids, but there are duplicates. Try this:
select t1.id, count(*)
from t1
group by t1.id
having count(*) > 1;
and
select t2.id, count(*)
from t2
group by t2.id
having count(*) > 1;
If you have duplicates, try:
WITH Dups AS(
SELECT ID, COUNT(ID) OVER (PARTITION BY ID) AS DupCount
FROM Table1)
SELECT *
FROM Dups
WHERE DupCount > 1;
If you need to delete the dups, you can use the following syntax:
WITH Dups AS(
SELECT ID, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY ID) AS DupCount
FROM Table1)
DELETE FROM Dups
WHERE DupCount > 1;
Obviously, however, check the data before you run a DELETE statement you got from a random on the internet. ;)
I Guess u have data type mismatch between 2 tables, cast them to integers and try your first query
select table1.ID from table1
where cast(ID as int) not in (select cast(ID as int) from table2)
If you have stored in a different format than int, cast them to varchar and
try with this datatype.
Not in takes longer to execute, use left join instead
select t1id from
(
select t1.id t1Id, t2.Id t2Id from table1 left join table2
on cast(t1.id as int) = cast(t2.id as int)
) x where t2Id is null
Suppose, we have query like this:
SELECT
1
FROM DUAL WHERE
(SELECT id FROM table_1 t1 WHERE /*conditions*/)
IN
(SELECT id FROM table_1 t2 WHERE /*conditions*/)
I want to check if first query
SELECT id FROM table_1 t1 WHERE /*conditions*/
returns the same ids like the second query.
Of course this query (IN statement) doesn't work.
Try:
SELECT id FROM table_1 t1 WHERE /*conditions1*/ and id not in (SELECT id FROM table_1 t2 WHERE /*conditions2*/)
union
SELECT id FROM table_1 t1 WHERE /*conditions2*/ and id not in (SELECT id FROM table_1 t2 WHERE /*conditions1*/)
If both queries gives you the same id's the result should be empty.
This will return nothing if sets are equal:
SELECT id FROM table_1 t1 WHERE /*conditions*/
EXCEPT
SELECT id FROM table_1 t2 WHERE /*conditions*/
You can use EXCEPT.
EXCEPT returns distinct rows from the left input query that aren’t
output by the right input query.
EXCEPT sample in your case:
SELECT id
FROM table_1 AS t1
WHERE /*conditions*/
EXCEPT
SELECT id
FROM table_1 AS t2
WHERE /*conditions*/
Just as an alternative method that used Full Join in tsql:
SELECT CASE WHEN isnull(Count(*), 0) > 1 then 1 else 0 end as result
FROM (SELECT t1.id as t1_id, t2.id as t2_id FROM
(SELECT id FROM table1 WHERE /*conditions*/) As t1
Full Outer Join
(SELECT id FROM table2 WHERE /*conditions*/) As t2
On t1.id = t2.id
) As ft
WHERE ft.t1_id is null or ft.t2_id is null
And I think this can marked as a stupid way.
I have two tables in my SQL Database.
ID CDATE
1 12/04/14
2 14/05/14
3 20/01/14
ID NAME
1 A
2 A
3 B
But I need the output as below.
NAME CDATE
A 14/05/14
B 20/01/14
Do you have any suggestions for me ?
SELECT MAX(t1.CDATE), t2.NAME FROM table1 t1 LEFT JOIN table2 t2 ON t1.ID = t2.ID GROUP BY t2.NAME ORDER BY t1.CDATE DESC
Try this:
SELECT t1.cdate, t2.name
FROM table1 t1
LEFT JOIN table2 t2 ON t1.id=t2.id
ORDER BY t1.cdate DESC;
Edit:
SELECT s1.cdate,
t2.name
FROM table2 t2
LEFT JOIN
(SELECT ID, MAX(cdate) cdate FROM table1 GROUP BY ID
) s1
ON s1.id=t2.id
ORDER BY s1.cdate DESC;
EDIT: Since you changed the question...
SELECT TOP 2 n.NAME, d, CDATE
FROM Dates d
LEFT JOIN Names n ON d.ID=n.ID
ORDER BY d.CDATE;
To Make table you need to create relation between this table
http://www.w3schools.com/sql/sql_foreignkey.asp
and then to get data from two table
http://www.w3schools.com/sql/sql_join.asp