I'm trying to retrieve the latest invoice record (table may contains duplicate invoices) with all relevant adjustment details.
Unfortunately, the below SQL only able to retrieve a single line of record. (e.g. if the particular latest invoice has multiple charge code, it will only retrieve 1 of it)
SELECT a.Invoice, a.Shipment_Nbr, a.Invoice_date, b.Adjust_rsn, b.Adjust_date, c.Charge_code, c.Charge_Amt
FROM Invoicing a
Inner Join Adjust b
on a.Shipment_Nbr=b.Shipment_Nbr
Inner Join Charge c
on b.uniq_id=c.uniq_id
WHERE b.Adjust_date between '05-01-2022' and '05-31-2022'
QUALIFY ROW_NUMBER () OVER (PARTITION BY
a.Shipment_Nbr
ORDER BY a.Invoice_date DESC) = 1
Refer to the image on the tables, current result and the expected result.
Tables, Current Result & Expected Result
This should probably do it
select
a.Invoice, b.Shipment_Nbr, a.Invoice_date, b.Adjust_rsn, b.Adjust_date, c.Charge_code, c.Charge_Amt
FROM
(
select * from Invoicing a
qualify (row_number() over (partition by Shipment_Nbr order by Invoice_date desc)=1)
) a
inner join
(
select * from Adjust b
qualify (row_number() over (partition by Shipment_Nbr order by Adjust_date desc)=1)
) b on (a.Shipment_Nbr=b.Shipment_Nbr)
inner join Charge c on (b.Uniq_Id=c.Uniq_Id)
) -- FROM
Related
I would like to use the LIMIT option in my query, but the number of expected rows is stored in another table. This is what I have, but it doesn't work:
select * from table1 limit (select limitvalue from table2 where id = 1)
When I only run the subquery, the result is 6, as expected.
I prefer working with a WITH statement if possible, but that didn't work eiter.
Thank you in advance!
You could use a prepared statement to get the limit of queries from the other table because the limit clause does not allow non constant variables as parameter:
PREPARE firstQuery FROM "SELECT * FROM table1 LIMIT ?";
SET #limit = (select limitvalue from table2 where id = 1);
EXECUTE firstQuery USING #limit;
The source of the sql query from another post
You can make use of MariaDB's ROW_NUMBER function in a CTE to count the rows to be output, comparing that against the limitvalue. For example:
WITH rownums AS (
SELECT *,
ROW_NUMBER() OVER () AS rn
FROM table1
)
SELECT *
FROM rownums
WHERE rn <= (SELECT limitvalue FROM table2 WHERE id = 1)
Note Using LIMIT without ORDER BY is not guaranteed to give you the same results every time. You should include an ORDER BY clause in the OVER part of the ROW_NUMBER window function. With the sample data in my demo, you might use something like:
ROW_NUMBER() OVER (ORDER BY mark DESC)
Demo on dbfiddle
I have the following DB structure:
tbl_record(_id,_id_user,...)
tbl_photo(_id,_id_record,...)
tbl_note(_id,_id_record,...)
When listing the records of a specific user while counting the number of photos a record has, I use the following query, which works fine:
SELECT tbl_record._id, COUNT(tbl_photo._id_record) AS photo_count FROM tbl_record
LEFT OUTER JOIN tbl_photo ON tbl_record._id=tbl_photo._id_record
WHERE tbl_record._id_user=? GROUP BY tbl_record._id;
Now, I'd like to do the same as above, but also count the number of notes a record has:
SELECT tbl_record._id, COUNT(tbl_photo._id_record) AS photo_count, COUNT(tbl_note._id_record) AS note_count FROM tbl_record
LEFT OUTER JOIN tbl_photo ON tbl_record._id=tbl_photo._id_record
LEFT OUTER JOIN tbl_note ON tbl_record._id=tbl_note._id_record
WHERE tbl_record._id_user=? GROUP BY tbl_record._id;
The count of the 2nd query does not work properly when a record has >0 photos & >0 notes, e.g. 3 photos & 5 photos which results in a count of 15 (3*5) for each.
Any idea how to make the 2nd query return the proper counts?
Thanks!!
You might be able to filter out duplicates by using COUNT(DISTINCT some_id), but this would be inefficient.
Better use correlated subqueries:
SELECT _id,
(SELECT COUNT(*)
FROM tbl_photo
WHERE _id_record = tbl_record._id
) AS photo_count,
(SELECT COUNT(*)
FROM tbl_note
WHERE _id_record = tbl_record._id
) AS note_count
FROM tbl_record
WHERE _id_user = ?
I need to write SQL that keeps only the minimum 5 records per each identifiable record in a table. For this, I use partition by and delete all records where the value returned is greater than 5. When I attempt to use the WHERE clause in the same query as the partition by statement, I get the error "Ordered Analytical Functions not allowed in WHERE Clause". So, in order to get it to work, I have to use three subqueries. My SQL looks ilke this:
delete mydb.mytable where (field1,field2) in
(
select field1,field2 from
(
select field1,field2,
Rank() over
(
partition BY field1
order by field1,field2
) n
from mydb.mytable
) x
where n > 5
)
The innermost subquery just returns the raw data. Since I can't use WHERE there, I wrapped it with a subquery, the purpose of which is to 1) use WHERE to get records greater than 5 in rank and 2) select only field1 and field2. The reason why I select only those two fields is so that I can use the IN statement for deleting those records in the outermost query.
It works, but it appears a bit cumbersome. I'd like to consolidate the inner two subqueries into a single subquery. Is this possible?
Sounds like you need to use the QUALIFY clause which is the HAVING clause for Window Aggregate functions. Below is my take on what you are trying to accomplish.
Please do not run this SQL directly against your production data without first testing it.
/* Physical Delete */
DELETE TGT
FROM MyDB.MyTable TGT
INNER JOIN
(SELECT Field1
, Field2
FROM MyDB.MyTable
QUALIFY ROW_NUMBER() (PARTITION BY Field1, ORDER BY Field1,2)
> 5
) SRC
ON TGT.Field1 = SRC.Field1
AND TGT.Field2 = SRC.Fileld2
/* Logical Delete */
UPDATE TGT
FROM MyDB.MyTable TGT
,
(SELECT Field1
, Field2
FROM MyDB.MyTable
QUALIFY ROW_NUMBER() (PARTITION BY Field1, ORDER BY Field1,2)
> 5
) SRC
SET Deleted = 'Y'
/* RecordExpireDate = Date - 1 */
WHERE TGT.Field1 = SRC.Field1
AND TGT.Field2 = SRC.Fileld2
I have a table and a relation
I have maybe 10 Submissions, but when I query the database I only want to get those with a Unique CaseId and the one to return should be the one with the newest Date. Is it possible (And adviceable) to do this in a single query or should I do the filtering in my asp.nets code behind where I fetch the data?
Edit: New images
Here you can see that I show many items with the same case id, I only want to show the latest one (Based on date)
This is my current sql query
SELECT Submission.Id, Date, center.Name as CenterName, center.Id as CenterId, subject.Name as SubjectName, subject.Id as SubjectId, EmployeeName, Reason, Description, Explanation, Done, ChiefLevel, Action, CaseId
FROM Submission, subject, center
WHERE center.Id=CenterId AND subject.Id=SubjectId
ORDER BY Date DESC;
SELECT caseid
FROM
(
SELECT caseid, max(date) AS max_date
FROM submission
GROUP BY caseid
) a
JOIN subject t ON a.subjectid=t.id
My QUERY ended up being this
SELECT s.Id, s.Date, c.Name as CenterName, c.Id as CenterId, su.Name as SubjectName, su.Id as SubjectId, s.EmployeeName, s.Reason, s.Description, s.Explanation, s.Done, s.ChiefLevel, s.Action, s.CaseId
FROM submission as s
INNER JOIN
(
SELECT CaseId, MAX(Date) AS MaxDateTime
FROM submission
GROUP BY CaseId
) as groupeds
ON s.CaseId = groupeds.CaseId
AND s.`Date` = groupeds.MaxDateTime
INNER JOIN
(
SELECT Id, Name
FROM subject
) as su
ON su.Id=SubjectId
INNER JOIN
(
SELECT Id, Name
FROM center
) as c
ON c.Id=CenterId;
I am trying to do an SQL query on two tables to retrieve multiple columns with a certain column (PostID) to be distinct (and it is not the primary key of the that table).
In addition, I need the selected distinct rows to be the latest (one of the columns retrieved is the entry date).
Detailed description:
I am building a forum like application, using 3 tables to store data.
I use table1 to store user details, table2 to store the meta data for posts, table3 to store the post details, updates, and replies (postID is unique in table2 pointing towards an original post, while in table3, it is used to show the original post and updates and replies).
Table columns:
table1 (UserID, FullName, mobile, etc.)
table2 (postID, UserID, EntryDate, Deleted columns)
table3 (postdetailsId, PostID, UserID, Entrydate, etc.)
I am trying to retrieve all the posts for 1 user in a gridview, my SQL query uses the USERID to retrieve all his posts from the table. However, it is retrieving the original post and all its updates, and I only want to retrieve the latest update of each post.
How can it be done fully in SQL (I know I can do it in C# with the returned results)?
My query:
SELECT T1.FullName, T3.PostID, T3.EntryDate, T3.Title
FROM Table1 as T1, Table3 as T3
WHERE T3.UserID = T1.UserID
AND T3.UserID = #UserID
You could use GROUP BY PostID along with MAX(EntryDate)
SELECT *
FROM (
SELECT posts.*, ROW_NUMBER() OVER (PARTITION BY post_updates.UserID, post_updates.PostID ORDER BY post_updates.EntryDate DESC) AS rn
FROM table1 users
JOIN table3 post_updates
ON post_updates.userID = users.UserID
WHERE users.UserID = #UserID
) q
WHERE rn = 1