UsingCoaslesce function with distinct - sql

I'm trying to fetch some data from a relational database and order it based on the payed_at column. In case payed_at is null, I want he updated_at column to be used instead. My query so far is bellow:
SELECT DISTINCT "orders".*
FROM "orders" INNER JOIN "order_items" ON "order_items"."order_id" = "orders"."id"
WHERE (orders.state = 'payed') AND (physical = true) AND (kind = 'output')
ORDER BY coalesce(orders.payed_at, orders.updated_at) DESC
LIMIT 200 OFFSET 0
I'm getting the following error from Postgres:
PG::Error: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list
It might be a problem with DISTINCT in the query, because when I remove DISTINCT word I get no error.
I'm using the coalesce function.
I'm stuck with this error.

The error states that when using SELECT DISTINCT and ordering by an expression, you must include the expression in the SELECT list. Your expression is the COALESCE.
SELECT DISTINCT coalesce(orders.payed_at, orders.updated_at),...
FROM "orders"
INNER JOIN "order_items" ON "order_items"."order_id" = "orders"."id"
WHERE (orders.STATE = 'payed')
AND (physical = true)
AND (kind = 'output')
ORDER BY coalesce(orders.payed_at, orders.updated_at) DESC LIMIT 200 OFFSET 0

Related

SQL Selecting data from 3 tables using GROUP BY

I am trying to write a formula to pull data from 3 tables and struggling to get it working.
I need to use the InventoryNbr from table s and do a group by, because there is many of the same InventoryNbr's, and I just want the MAX IndexListID Returned. The IndexListID is a Unique Key, so when I search on table il, I should only return 1 row. I want to then pull the end year from that row as well as the modelnm, and use those 2 values to get the CarlineNm. Here is my code:
SELECT s.InventoryNbr, MAX(s.IndexListID) AS IndexListID, il.EndYear, c.CarlineNm
FROM sysidla as s
INNER JOIN IndexList as il
ON s.IndexListID = il.IndexListID
INNER JOIN Carline as c
ON il.EndYear = c.CarlineYear
AND il.ModelNm = c.ModelNm
GROUP BY InventoryNbr
ORDER BY InventoryNbr ASC;
The error I keep getting is:
Column 'IndexList.EndYear' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Here is some sample data:
sysidla
InventoryNbr|IndexListID|Junk|Junk2
12345|1|x|y
12345|2|c|r
12345|3|c|e
12346|4|e|w
IndexList
ModelNm|Junk|Junk1|Junk3|EndYear|IndexListID
name1|c|f|r|2004|1
name2|c|f|r|2008|2
name3|c|f|r|2012|3
name4|c|f|r|2004|4
name5|c|f|r|2018|5
Carline
CarlineYear|CarlineNm|Junk9|ModelNm
2005|NAME|d|name1
2012|NAME22|d|name3
2005|NAME354|d|name4
2005|NAME1|d|name5
So for instance, this is an incomplete data sample because every IndexListID will have a match in IndexList, but I want to be able match InventoryNbr 12345 and select the max INDEXLISTID which is 3, then use 3 on IndexList to grab name3 and 2012. Then I want to use 2012 and name3 to get NAME22 From Carine.
Use window functions in a subquery:
SELECT s.InventoryNbr, s.IndexListID, il.EndYear, c.CarlineNm
FROM (SELECT s.*,
ROW_NUMBER() OVER (PARTITION BY il.IndexListID ORDER BY il.IndexListID DESC) as seqnum
FROM sysidla s
) s INNER JOIN
IndexList il
ON s.IndexListID = il.IndexListID INNER JOIN
Carline c
ON il.EndYear = c.CarlineYear AND
il.ModelNm = c.ModelNm
WHERE seqnum = 1
ORDER BY InventoryNbr ASC;
No aggregation is needed.
Your are getting this error because, there is a problem with your group by and SELECT section . You can not select column while using group by like this. Either you have to use an aggregate function or your column should in the group by to select like this.
So,Here is a solution you can check =>
SELECT T.*,il.EndYear, c.CarlineNm FROM
(SELECT s.InventoryNbr, MAX(s.IndexListID) AS IndexListID
FROM sysidla as s
GROUP BY InventoryNbr) T
INNER JOIN IndexList as il ON T.IndexListID = il.IndexListID
INNER JOIN Carline as c ON il.EndYear = c.CarlineYear AND il.ModelNm = c.ModelNm
ORDER BY T.InventoryNbr ASC;
Note: This code is not optimized. Sub-query is little slow however, you can optimize that using window function (CTE). Please check and let me know.

SQL error on ORDER BY in subquery (TOP is used)

I am getting Syntax error near 'ORDER' from the following query:
SELECT i.ItemID, i.Description, v.VendorItemID
FROM Items i
JOIN ItemVendors v ON
v.RecordID = (
SELECT TOP 1 RecordID
FROM ItemVendors iv
WHERE
iv.VendorID = i.VendorID AND
iv.ParentRecordID = i.RecordID
ORDER BY RecordID DESC
);
If I remove the ORDER BY clause the query runs fine, but unfortunately it is essential to pull from a descending list rather than ascending. All the answers I have found relating to this indicate that TOP must be used, but in this case I am already using it. I don't have any problems with TOP and ORDER BY when not part of a subquery. Any ideas?
This error has nothing to do with TOP.
ASE simply does not allow ORDER BY in a subquery. That's the reason for the error.
RecordID in the ORDER BY is ambiguous. Add the appropriate table alias in front of it (e.g., iv.RecordID).
I'd use max instead of top 1 ... order by
SELECT i.ItemID, i.Description, v.VendorItemID
FROM Items i
JOIN ItemVendors v ON
v.RecordID = (
SELECT max(RecordID)
FROM ItemVendors iv
WHERE
iv.VendorID = i.VendorID AND
iv.ParentRecordID = i.RecordID);

error is Reason for Column is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause

I got an error
Column 'Employee.EmpID' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
SQL code:
with cte(stu_id,term_cd, spcl_cd ) as
(
Select
zt.[STU_ID], zt.TERM_CD, zt.SPCL_CD
From
SR0TZT(nolock) zt
Inner Join
(Select
STU_ID, MIN(TERM_SEQ_NUM) MinPoint, SPCL_CD
From SR0TZT
Group By STU_ID) tbl1 On zt.STU_ID = tbl1.STU_ID
Where
tbl1.MinPoint = zt.TERM_SEQ_NUM
and zt.STU_ID = '202716354'
and tbl1.SPCL_CD = zt.SPCL_CD
)
SELECT
zt.[STU_ID], zt.[TERM_CD], zt.[SPCL_CD],
zt.[SPCL_STRT_TERM], zt.TERM_SEQ_NUM, t.term_id
FROM
SR0TZT zt
JOIN
cte ON zt.STU_ID = cte.stu_id
WHERE
zt.STU_ID = '202716354'
Condition is:
For each unique combination of TZT.STU_ID and TZT.SPCL_CD where TZT.COLL_CD = '', display the TZT.TERM_CD with the minimum TZT.TERM_SEQ_NUM.
For UID 202716354, based on the above rule, the value of this column is incorrect for both specialization codes.
Not sure I understand why you are getting an error for 'Employee.EmpID' as it doesn't appear in your query.
At first look I can see that the following part of your SQL code (the derived table 'tbl1')...
Select STU_ID,MIN(TERM_SEQ_NUM) MinPoint,SPCL_CD From SR0TZT Group By STU_ID
..is incorrect and would cause a similar error because SPCL_CD isn't used in an aggregate function (such as MIN) or in the GROUP BY. You should change it to:-
Select STU_ID,MIN(TERM_SEQ_NUM) MinPoint,SPCL_CD From SR0TZT Group By STU_ID, SPCL_CD
And that should solve your problem.
Your problem is in this below script:
Select STU_ID,MIN(TERM_SEQ_NUM) MinPoint,SPCL_CD From SR0TZT Group By STU_ID
It should be:
Select STU_ID,MIN(TERM_SEQ_NUM) MinPoint,SPCL_CD From SR0TZT Group By STU_ID, SPCL_CD
Every column that you put in select, you should put them too in group by.

Doing an Update Ignore in SQL Server 2005

I have a table where I wish to update some of the rows. All the fields are not null. I'm doing a sub-query, and I wish to update the table with the non-Null results.
See Below for my final answer:
In MySQL, I solve this problem by doing an UPDATE IGNORE. How do I make this work in SQL Server 2005? The sub-query uses a four-table Join to find the data to insert if it exists. The Update is being run against a table that could have 90,000+ records, so I need a solution that uses SQL, rather than having the Java program that's querying the database retrieve the results and then update those fields where we've got non-Null values.
Update: My query:
UPDATE #SearchResults SET geneSymbol = (
SELECT TOP 1 symbol.name FROM
GeneSymbol AS symbol JOIN GeneConnector AS geneJoin
ON symbol.id = geneJoin.geneSymbolID
JOIN Result AS sSeq ON geneJoin.sSeqID = sSeq.id
JOIN IndelConnector AS joiner ON joiner.sSeqID = sSeq.id
WHERE joiner.indelID = #SearchResults.id ORDER BY symbol.id ASC)
WHERE isSNV = 0
If I add "AND symbol.name IS NOT NULL" to either WHERE I get a SQL error. If I run it as is I get "adding null to a non-null column" errors. :-(
Thank you all, I ended up finding this:
UPDATE #SearchResults SET geneSymbol =
ISNULL ((SELECT TOP 1 symbol.name FROM
GeneSymbol AS symbol JOIN GeneConnector AS geneJoin
ON symbol.id = geneJoin.geneSymbolID
JOIN Result AS sSeq ON geneJoin.sSeqID = sSeq.id
JOIN IndelConnector AS joiner ON joiner.sSeqID = sSeq.id
WHERE joiner.indelID = #SearchResults.id ORDER BY symbol.id ASC), ' ')
WHERE isSNV = 0
While it would be better not to do anything in the null case (so I'm going to try to understand the other answers, and see if they're faster) setting the null cases to a blank answer also works, and that's what this does.
Note: Wrapping the ISNULL (...) with () leads to really obscure (and wrong) errors.
with UpdatedGenesDS (
select joiner.indelID, name, row_number() over (order by symbol.id asc) seq
from
GeneSymbol AS symbol JOIN GeneConnector AS geneJoin
ON symbol.id = geneJoin.geneSymbolID
JOIN Result AS sSeq ON geneJoin.sSeqID = sSeq.id
JOIN IndelConnector AS joiner ON joiner.sSeqID = sSeq.id
WHERE name is not null ORDER BY symbol.id ASC
)
update Genes
set geneSymbol = upd.name
from #SearchResults a
inner join UpdateGenesDs upd on a.id = b.intelID
where upd.seq =1 and isSNV = 0
this handles the null completely as all are filtered out by the where predicate (can also be filtered by join predicate if You wish. Is it what You are looking for?
Here's another option, where only those rows in #SearchResults that are succesfully joined will be udpated. If there are no null values in the underlying data, then the inner joins will pull in no null values, and you won't have to worry about filtering them out.
UPDATE #SearchResults
set geneSymbol = symbol.name
from #SearchResults sr
inner join IndelConnector AS joiner
on joiner.indelID = sr.id
inner join Result AS sSeq
on sSeq.id = joiner.sSeqID
inner join GeneConnector AS geneJoin
on geneJoin.sSeqID = sSeq.id
-- Get "lowest" (i.e. first if listed alphabetically) value of name for each id
inner join (select id, min(name) name
from GeneSymbol
group by id) symbol
on symbol.id = geneJoin.geneSymbolID
where isSNV = 0 -- Which table is this value from?
(There might be some syntax problems, without tables I can't debug it)

MySQL subquery returns more than one row

I am executing this query:
SELECT
voterfile_county.Name,
voterfile_precienct.PREC_ID,
voterfile_precienct.Name,
COUNT((SELECT voterfile_voter.ID
FROM voterfile_voter
JOIN voterfile_household
WHERE voterfile_voter.House_ID = voterfile_household.ID
AND voterfile_household.Precnum = voterfile_precienct.PREC_ID)) AS Voters
FROM voterfile_precienct JOIN voterfile_county
WHERE voterfile_precienct.County_ID = voterfile_County.ID;
I am trying to make it return something like this:
County_Name Prec_ID Prec_Name Voters(Count of # of voters in that precienct)
However, I am getting the error:
#1242 - Subquery returns more than 1 row.
I have tried placing the COUNT statement in the subquery but I get an invalid syntax error.
If you get error:error no 1242 Subquery returns more than one row, try to put ANY before your subquery. Eg:
This query return error:
SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);
This is good query:
SELECT * FROM t1 WHERE column1 = ANY (SELECT column1 FROM t2);
You can try it without the subquery, with a simple group by:
SELECT voterfile_county.Name,
voterfile_precienct.PREC_ID,
voterfile_precienct.Name,
count(voterfile_voter.ID)
FROM voterfile_county
JOIN voterfile_precienct
ON voterfile_precienct.County_ID = voterfile_County.ID
JOIN voterfile_household
ON voterfile_household.Precnum = voterfile_precienct.PREC_ID
JOIN voterfile_voter
ON voterfile_voter.House_ID = voterfile_household.ID
GROUP BY voterfile_county.Name,
voterfile_precienct.PREC_ID,
voterfile_precienct.Name
When you use GROUP BY, any column that you are not grouping on must have an aggregate clause (f.e. SUM or COUNT.) So in this case you have to group on county name, precienct.id and precient.name.
Try this
SELECT
voterfile_county.Name, voterfile_precienct.PREC_ID,
voterfile_precienct.Name,
(SELECT COUNT(voterfile_voter.ID)
FROM voterfile_voter JOIN voterfile_household
WHERE voterfile_voter.House_ID = voterfile_household.ID
AND voterfile_household.Precnum = voterfile_precienct.PREC_ID) as Voters
FROM voterfile_precienct JOIN voterfile_county
ON voterfile_precienct.County_ID = voterfile_County.ID
See the below example and modify your query accordingly.
select COUNT(ResultTPLAlias.id) from
(select id from Table_name where .... ) ResultTPLAlias;