how to change this MYSQL query to sql server
SELECT
id.value AS ICDCode,
items.itemName AS ProblemListDescription,
COUNT(*) as UsageCount
FROM problemlist pl
INNER JOIN items
ON pl.asmtId = items.itemId
LEFT OUTER JOIN itemdetail id
ON (items.itemId=id.itemId AND id.propId=13 )
WHERE (pl.SNOMED='' OR pl.SNOMED IS NULL) AND pl.deleteflag=0
group by id.value, items.itemName
ORDER BY UsageCount DESC, ICDCode ASC
LIMIT 0,10 ;
I have tried this for sql server but its throwing error
select * from
(
SELECT
id.value AS ICDCode,
items.itemName AS ProblemListDescription,
COUNT(*)as UsageCount ,
row_number() over (ORDER BY UsageCount DESC, ICDCode ASC ) as rownum
FROM problemlist pl
INNER JOIN items
ON pl.asmtId=items.itemId
LEFT OUTER JOIN itemdetail id
ON (items.itemId=id.itemId AND id.propId=13 )
WHERE (pl.SNOMED='' OR pl.SNOMED IS NULL) AND pl.deleteflag=0
group by id.value, items.itemName
) sno
WHERE rownum BETWEEN 0 AND 10 ;
error message is
column usagecount is invalid
column icdcode is invalid
what is the mistake or i have to do it in another way ? guide me
I would probably just use TOP here:
SELECT TOP 10
id.value AS ICDCode,
items.itemName AS ProblemListDescription,
COUNT(*) as UsageCount
FROM problemlist pl
INNER JOIN items
ON pl.asmtId = items.itemId
LEFT OUTER JOIN itemdetail id
ON (items.itemId=id.itemId AND id.propId=13 )
WHERE (pl.SNOMED='' OR pl.SNOMED IS NULL) AND pl.deleteflag=0
GROUP BY
id.value,
items.itemName
ORDER BY
UsageCount DESC, ICDCode
By the way, the error in your query is that you were referring to an alias in the ROW_NUMBER function, but the alias is not yet available at that point in the query. You could use the following instead:
ROW_NUMBER() OVER (ORDER BY COUNT(*) DESC, ICDCode) AS rownum
Related
I'm moving a project from MySQL to MSSQL. And since I have a non-standard use of grouping on the Mssql side, I can't bring up the correct data. I need a suggestion. The stok_adet field displays the wrong data. How can we overcome this? Thank you in advance for your help.
My current screenshots are as follows.
Mssql Query
SELECT sm.*,
(SELECT COUNT(*)
FROM stok_durum d
WHERE sm.stok_durum_id = sm.stok_durum_id
) as stok_adet
FROM (SELECT s.*, m.*,
ROW_NUMBER() OVER (PARTITION BY s.bundle_no, s.boy, s.yukseklik, s.hatali
ORDER BY (SELECT NULL)
) as seqnum
FROM stok s
CROSS JOIN mermer_cins m
WHERE m.mermer_cins_id = '5' AND s.blok_no = 'M6320'
) sm
WHERE seqnum = 1
ORDER BY sm.blok_no ASC, sm.bundle_no ASC, sm.stok_tarih DESC
MySql side
SELECT Count(*) AS stok_adet, s.*, m.*,d.*
FROM stok AS s
CROSS JOIN mermer_cins AS m
JOIN stok_durum AS d ON s.stok_durum_id = d.stok_durum_id
WHERE m.mermer_cins_id = '5' AND s.blok_no = 'M6320'
GROUP BY s.bundle_no, s.boy, s.yukseklik, s.hatali
ORDER BY s.blok_no ASC, s.bundle_no ASC, s.stok_tarih DESC
MsSql side
MySql side
When calculating stok_adet you have a comparison between the same column:
WHERE sm.stok_durum_id = sm.stok_durum_id
but you maybee want:
WHERE d.stok_durum_id = sm.stok_durum_id
Try:
SELECT sm.*,
(SELECT COUNT(*)
FROM stok_durum d
WHERE d.stok_durum_id = sm.stok_durum_id
) as stok_adet
FROM (SELECT s.*, m.*,
ROW_NUMBER() OVER (PARTITION BY s.bundle_no, s.boy, s.yukseklik, s.hatali
ORDER BY (SELECT NULL)
) as seqnum
FROM stok s
CROSS JOIN mermer_cins m
WHERE m.mermer_cins_id = '5' AND s.blok_no = 'M6320'
) sm
WHERE seqnum = 1
ORDER BY sm.blok_no ASC, sm.bundle_no ASC, sm.stok_tarih DESC
I want to share some SQL queries that I use for paging when a joined table and ordering is needed.
In these examples, the result set is limited to row numbers 2-3.
MySql 5.1:
SELECT outerO.Id, outerO.Value
FROM MyTable outerO
WHERE outerO.id IN (
SELECT DISTINCT o.id FROM MyTable o
JOIN LinkTable l ON l.Fk = o.Id
WHERE o.Value LIKE ? ESCAPE '!'
)
ORDER BY outerO.Value DESC, outerO.Id ASC
LIMIT 2
OFFSET 1
This one shows best what I want to achieve. Oracle 11 and DB2 are much more complicated.
Oracle 11:
SELECT outerO.Id, outerO.Value
FROM MyTable outerO
WHERE outerO.id IN (
SELECT id FROM(
SELECT row_.id, rownum rownum_
FROM (
SELECT id
FROM (
SELECT DISTINCT o.Value, o.Id
FROM MyTable o
JOIN LinkTable l ON l.Fk = o.Id
WHERE o.Value LIKE ? ESCAPE '!'
ORDER BY o.Value DESC, o.Id ASC
)
) row_ WHERE rownum <= 3
) WHERE rownum_ > 1
)
ORDER BY outerO.Value DESC, outerO.Id ASC
I found no way to do this with fewer subselects.
DB2 10.5:
SELECT outerO.Id, outerO.Value
FROM MyTable outerO
WHERE outerO.id IN (
SELECT inner1_.id
FROM (
SELECT inner2_.id, rownumber()
OVER(ORDER BY ORDER OF inner2_) AS rownumber_
FROM (
SELECT id
FROM (
SELECT DISTINCT o.Value, o.Id
FROM MyTable o
JOIN LinkTable l ON l.Fk = o.Id
WHERE o.Value LIKE ? ESCAPE '!'
ORDER BY o.Value DESC, o.Id ASC
)
FETCH FIRST 3 ROWS ONLY
) AS inner2_
) AS inner1_
WHERE inner1_.rownumber_ > 1 ORDER BY inner1_.rownumber_
)
ORDER BY outerO.Value DESC, outerO.Id ASC
I found no way to do this with fewer subselects.
Microsoft SQL-Server 2016:
SELECT outerO.Id, outerO.Value
FROM MyTable outerO
WHERE outerO.id IN (
SELECT DISTINCT o.id
FROM MyTable o
JOIN LinkTable l ON l.Fk = o.Id
WHERE o.Value LIKE ? ESCAPE '!'
)
ORDER BY outerO.Value DESC, outerO.Id ASC
OFFSET 1 ROWS
FETCH NEXT 2 ROWS ONLY
These queries do work for me, but perhaps there are better solutions available?
This is how I would do it in DB2
SELECT ID, VALUE
FROM (
SELECT ID, VALUE,
ROW_NUMBER() OVER (ORDER BY o.Value DESC, o.Id ASC) AS RN
FROM MyTable
JOIN LinkTable l ON l.Fk = o.Id
WHERE o.Value LIKE ? ESCAPE '!'
ORDER BY o.Value DESC, o.Id ASC
) X
WHERE RN > 1 AND RN <= 3
Is it possible to convert this subquery to join?
SELECT `news`.`newsId`,
(SELECT `comments`.`text`
FROM `comments`
WHERE `comments`.`newsId` = `news`.`newsId`
order by `comments`.`date` desc
limit 1)
FROM `news` , `comments`
where `news`.`newsId` = `comments`.`newsId`
GROUP BY `news`.`newsId`
order by news.date desc;
I assume newsId is unique.
SELECT `news`.`newsId`,
`comments`.`text`
FROM `news`
CROSS APPLY (SELECT `comments`.`text`
FROM `comments`
WHERE `comments`.`newsId` = `news`.`newsId`
order by `comments`.`date` desc
limit 1) cm
order by news.date desc;
I think that what you're trying to do is:
SELECT n.newsId FROM news n
INNER JOIN comments c ON c.newsId = n.newsId
ORDER BY c.date DESC, n.date
LIMIT 1
The GROUP BY is not necessary as you are not using any aggregation function. You can have unique entries with DISTINCT
I don't understund why sorting didin't work correctly with "ORDER BY average, votes DESC", because i need highest average and votes are going from the top to bottom, but DESC didin't solve what thing. My result in var_dump http://pastie.org/private/b05smuh0fvw72wwp2w1zq highest entrie is in the bottom, but i need start from the top and going to the bottom.
SELECT c.*, r.votes, c.total_comments,
ROUND(sumrate / votes) AS average
FROM catalog c LEFT JOIN
(SELECT r.object_id, COUNT(*) as votes, SUM(r.rate) as sumrate
FROM ratings r
GROUP BY r.object_id
) r
ON r.object_id = c.catalog_id LEFT JOIN
(SELECT c.catalog_id, COUNT(*) as total_comments
FROM comments c
GROUP BY c.catalog_id
) c
ON c.catalog_id = c.catalog_id
GROUP BY c.catalog_id
ORDER BY average, votes DESC;
Because you can define the order for every column and not just the order by in total. The default is ASC.
Your order
ORDER BY average, votes DESC
turn automatically into
ORDER BY average ASC, votes DESC
But you are looking for
ORDER BY average DESC, votes DESC
You need to specify DESC for both the columns. Otherwise by default it is ASC
SELECT c.*, r.votes, c.total_comments,
ROUND(sumrate / votes) AS average
FROM catalog c LEFT JOIN
(SELECT r.object_id, COUNT(*) as votes, SUM(r.rate) as sumrate
FROM ratings r
GROUP BY r.object_id
) r
ON r.object_id = c.catalog_id LEFT JOIN
(SELECT c.catalog_id, COUNT(*) as total_comments
FROM comments c
GROUP BY c.catalog_id
) c
ON c.catalog_id = c.catalog_id
GROUP BY c.catalog_id
ORDER BY average DESC, votes DESC;
I have a table called Request.
Other tables are linked to the Request table through a request id.
There is a TwitterTweet table and a FacebookPost table.
So a single request can have 50 TwitterTweets and/or 20 FacebookPosts or any amount of Tweets/Posts
We can add them together for a total count of 70.
I'm trying to create a query that could tell me what is the request with the highest total count.
I know this is wrong:
(I attempted to just order them by the counts within the TwitterTweet, but it would not let me do an OUTER JOIN which I thought
would bring back the Count.count column. It forced me to do a Left Join for it to compile. My Logic was to do a join so
that the results were calculated for each row by the requestid)
SELECT r1.`id` AS requestid, r1 . *
FROM `Request` AS r1
LEFT JOIN
(SELECT COUNT( * ) AS count, rid
FROM
((SELECT `TwitterTweet`.`id` AS `smid` , `TwitterTweet`.`requestid` AS rid
FROM `TwitterTweet`
WHERE `TwitterTweet`.`requestid` = requestid
AND `TwitterTweet`.`active` =1) AS talias
)) AS Count ON ( Count.rid = requestid )
ORDER BY Count.count
*When I tried to add in the Facebook side it would not compile any more
(The concept is that the results are added from TwitterTweet with the results from FacebookPost
that are attached to the specific requestid which would give us a count. The entire result
set should be ordered by that count)
SELECT r1.`id` AS requestid, r1 . *
FROM `Request` AS r1
LEFT JOIN
(SELECT COUNT( * ) AS count, rid
FROM
((SELECT `TwitterTweet`.`id` AS `smid` , `TwitterTweet`.`requestid` AS rid
FROM `TwitterTweet`
WHERE `TwitterTweet`.`requestid` = requestid
AND `TwitterTweet`.`active` =1 ) AS talias
UNION All
(SELECT `FacebookPost`.`id` AS `smid`, `FacebookPost`.`requestid` AS rid
FROM `FacebookPost`
WHERE `FacebookPost`.`requestid` = requestid
AND `FacebookPost`.`active` = 1) as falias
)) AS Count ON ( Count.rid = requestid )
ORDER BY Count.count
I updated the Query with an attempt to add an alias:
SELECT rid, SUM(count) total_count
FROM
(
(SELECT COUNT(*) AS count, r.rid
FROM request r
JOIN TwitterTweet tt
ON r.id = tt.requestid
WHERE tt.active = 1
GROUP BY r.rid) AS twitter
UNION ALL
(SELECT COUNT(*) AS count, r.rid
FROM request r
JOIN FacebookPost fp
ON r.id = fp.requestid
WHERE fp.active = 1
GROUP BY r.rid ) AS fbook
)
GROUP BY rid
ORDER BY SUM(count) DESC
I made another adjustment to give the middle subquery an alias, but now I only get one row returned with a zero in the rid column and 5686 in the total_count column...the 5686 might be all of the results.
SELECT counts.rid, SUM(count) total_count
FROM
(
SELECT COUNT(*) AS count, r.requestid AS rid
FROM request r
JOIN TwitterTweet tt
ON r.id = tt.requestid
WHERE tt.active = 1
GROUP BY r.requestid
UNION ALL
SELECT COUNT(*) AS count, r.requestid AS rid
FROM request r
JOIN FacebookPost fp
ON r.id = fp.requestid
WHERE fp.active = 1
GROUP BY r.requestid
) AS counts
GROUP BY counts.rid
ORDER BY SUM(count) DESC
Got it!!!
Thanks for your help guys, I had to remove those joins on the request:
SELECT counts.rid, SUM(count) total_count
FROM
(
SELECT COUNT(*) AS count, tt.requestid AS rid
FROM TwitterTweet tt
WHERE tt.active = 1
GROUP BY tt.requestid
UNION ALL
SELECT COUNT(*) AS count, fp.requestid AS rid
FROM FacebookPost fp
WHERE fp.active = 1
GROUP BY fp.requestid
) AS counts
GROUP BY counts.rid
ORDER BY SUM(count) DESC
SELECT id, SUM(count) total_count
FROM
(
SELECT COUNT(*) AS count, r.id
FROM request r
JOIN TwitterTweet tt
ON r.id = tt.requestid
WHERE tt.active = 1
GROUP BY r.id
UNION ALL
SELECT COUNT(*) AS count, r.id
FROM request r
JOIN FacebookPost fp
ON r.id = fp.requestid
WHERE fp.active = 1
GROUP BY r.id
) sub
GROUP BY id
ORDER BY SUM(count) DESC
;