SQL Server Max statement returns multiple results - sql

When querying two tables (t1, t2) and using a MAX statement for a column in t2, SQL returns multiple entries.
This seems to be because I also query other info from t2 which consists of unique entries.
Simplified table example
t1.number t2.number_id t2.sync_id t2.text
1 1 1 'My problem is
1 1 2 That
2 2 3 Multiple entries
2 2 1 Are
2 2 2 Returned'
When using
SELECT t1.number, max(t2.sync_id), convert(varchar(100),t2.text)
FROM t1, t2
WHERE t1.number = t2.number_id
GROUP BY t1.number, convert(varchar(100),t2.text)
I get multiple entries instead of just line 2 and 5 from the example table.

You need to remove convert(varchar(100),t2.text) from GROUP BY t1.number, convert(varchar(100),t2.text). You are now grouping by two criteria when you just want grouping by t1.number.
Also you may be interested on how to get all the text in the t2.text column in one single row. If so take a look here: http://databases.aspfaq.com/general/how-do-i-concatenate-strings-from-a-column-into-a-single-row.html

Assuming at least SQL 2005 so you can use a CTE:
;with cteMaxSync as (
select t1.number, max(t2.sync_id) as MaxSyncId
from t1
inner join t2
on t1.number = t2.number_id
group by t1.number
)
select c.number, c.MaxSyncId, convert(varchar(100),t2.text)
from cteMaxSync c
inner join t2
on c.number = t2.number_id
and c.MaxSyncId = t2.sync_id

Standard sql approach
SELECT
t1.number,
t2.sync_id,
convert(varchar(100),t2.text)
FROM
t1
INNER JOIN t2
ON t1.number = t2.number_id
INNER JOIN (
SELECT Max(t2.synch_id) synch_id, t1.number)
FROM t1
INNER JOIN t2
ON t1.number = t2.number_id ) max
ON t1.number = max.number and
t2.synch_id = max.synch_id

Related

SQL statement to check if data exists in one table and not in two other tables

I'm creating 1 temp table (temp1) using table1.
and I want to check if data from temp table is present in table1 and table2.
table1 and table2 have same columns.
It's difficult to assess exactly what you need without further detail, but you could try a LEFT JOIN and a COUNT here to indicate whether there are any matching rows (whereby anything over 0 indicates matching rows)
SELECT
COUNT(*) AS matching_rows
FROM
(
SELECT
1 AS 'ColumnA'
) AS T1
LEFT OUTER JOIN
(
SELECT
2 AS 'ColumnA'
) AS T2
ON T1.ColumnA = T2.ColumnA
WHERE
T2.ColumnA IS NOT NULL
You can also use an INNER JOIN for this:
SELECT
COUNT(*) AS matching_rows
FROM
(
SELECT
1 AS 'ColumnA'
) AS T1
INNER JOIN
(
SELECT
2 AS 'ColumnA'
) AS T2
ON T1.ColumnA = T2.ColumnA

How to join a table with another one and then with itself on SQL Server 2017?

I have 2 tables where Table1 (t1) has the main data and Table2 (t2) has the relations between data.
I need a query to get data from table (t1) where condition is like
WHERE t1.row = 1 AND t1.code = s1
But this query started with (t1 left join t2 on t1.row = t2.row) and then produced answer will join on t1 again on t2.trow = t1.row.
Then answer must have some columns and rows which is shown in bottom.
Can you help me with this query?
I wrote this query :
SELECT
t1.code, t1_1.bed, t1_1.bes,
t2.t1row, t2.t2row
FROM
dbo.t1
LEFT OUTER JOIN
dbo.t2 ON t1.row = t2.t1row
LEFT OUTER JOIN
dbo.t1 t1_1 ON t2.t2row = t1_1.row
WHERE
t1.code = s1 And t1.row = '1'
But this query returns 2 rows where I need 5 rows!
I'm not sure why you want to link back to t1, since simply joining t1 with t2 produces the desired result. If you SELECT DISTINCT then two similar rows are replaced by one
SELECT DISTINCT
t1.row,
CASE WHEN trow=1 THEN 'OK' ELSE null END AS t2_row,
t1.bed, t1.bes, t1.code
FROM
t1
LEFT JOIN t2
ON t1.row = t2.frow
WHERE t1.code='s1'
ORDER BY t1.row;
Result:
row t2_row bed bes code
1 10000 s1
2 OK 7500 s1
3 OK 2500 s1
4 20000 s1
5 20000 s1
Use a CASE for t2.trow column and DISTINCT to remove duplicates
SELECT DISTINCT row,
CASE WHEN trow = 1 THEN 'OK'
ELSE ''
END as t2_row,
bed, bes, code
FROM t1
LEFT JOIN t2 ON t1.row = frow
AND code = 's1'
I am thinking that this does what you want:
select t1.*,
(case when exists (select 1
from t2
where t2.frow = t1.row and
t2.frow <> 1
)
then 'OK'
end)
from t1
where t1.code = 's1';

How to get first row value from third table while joining three tables

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'

SQL Joining three tables and using LEFT OUTER JOIN

I have three tables and two seperate SQL queries which are working correctly and I am having correct results.
If I try to join these three tables I am having null as result.
First query:
select T1.ID,T3.COMPANY
from T1,T3
where (T1.status!='CLOSED') and (T1.PRIORITY)>5 and T1.CLASSID=T3.CLASSID
Second query:
SELECT T1.ID, T2.DESCRIPTION
FROM T1
LEFT OUTER JOIN T2
ON T1.ID=T2.KEY
WHERE T1.status!='CLOSED'
AND (T2.CREATEDATE= (SELECT MAX(CREATEDATE)
FROM T2
WHERE T2.KEY=T1.ID))
I tried to join them but as result I am having null:
select T1.ID,T3.COMPANY,T2.DESCRIPTION
from T1
INNER JOIN T3 ON T1.CLASSID=T3.CLASSID
LEFT OUTER JOIN T2
ON T1.ID=T2.KEY
where (T1.status!='CLOSED') AND (T1.PRIORITY)>5
AND (T2.CREATEDATE= (SELECT MAX(CREATEDATE)
FROM T2
WHERE T2.KEY=T1.ID))
like it does not recognized last part for taking MAX value from T2 table.
What am I doing wrong? Thanks for help
Firstly, use an alias for the subquery on table T2.
T2.CREATEDATE =
(SELECT MAX(T2Alias.CREATEDATE)
FROM T2 AS T2Alias
WHERE T2Alias.KEY = T1.ID)
Secondly, consider moving this condition into the ON clause of the LEFT JOIN to table T2.
The first thing that jumps out at me is the new dependency on both T1.Priority > 5 and T2.CreateDate value being equal to the result of the inline query:
( AND (T1.PRIORITY) > 5
AND (T2.CREATEDATE =
(SELECT MAX(CREATEDATE) FROM T2 WHERE T2.KEY = T1.ID) )
Without the data it's difficult to check however this may be the issue

SQL query with limit on rows from one table, not the result set

I'm running a simple query with a join, similar to
SELECT t1.a, t2.b FROM t1 LEFT JOIN t2 ON ... LIMIT 5
As t1 has-many rows in t2 ( any number above 2 ) the LIMIT statement does not return the first 5 rows from t1 and corresponding entries from t2, but 5 rows which usually include 2-3 rows from t1.
How can I write this query to get the first 5 rows from t1 and the corresponding entries from t2?
Using MySQL 5.0.45.
SELECT t3.a, t2.b FROM (SELECT * FROM t1 LIMIT 5) t3
LEFT JOIN t2 ON ...
Note that if you use limit without an 'order by' clause, it is not defined which 5 rows you will get. Consider adding an 'order by' clause if this is not what you want.
This is a classic pagination query. I suggest breaking it down into two queries:
SELECT DISTINCT t1.id FROM t1 LEFT JOIN t2 ON ... LIMIT 5
Take these id's and place them in the following query:
SELECT t1.a, t2.b FROM t1 LEFT JOIN t2 ON ... WHERE t1.id IN (?,?,?,?,?)
I believe the following will do the trick:
SELECT t1.a, (SELECT t2.b FROM t2 WHERE t2... = t1...) AS b FROM t1 LIMIT 5
You can group it by the unique column in t1:
SELECT * FROM t1 JOIN t2 ON ... GROUP BY t1.id LIMIT 5
But do you need the t2 table to be in a specific order?