Get Identity after selecting from distinct result - sql

i have 2 tables ( Model_Table , Items_Table)
Model_Tabl ( ID, ModelName, ModelQuantity)
Items_Tabl ( I_Code, IName, ID)
after inserting new row into (Model_Table) - Triggers insert multi row into (Items_Table) Depend on ModelQuantity from (Model_Table)
, and until now its work fine
I Created "select distinct ModelName , Sum(ModelQuantity) group by ModelName"
and i got result fine
My question is :
When i select model name from (DISTINCT) query i want to know which (ID) I selected from (Model_Table)
Model_ID (TO) Model_Name = 1 (TO) Many
ty

just do:
select ID, ModelName , Sum(ModelQuantity) group by ID, ModelName
as long as ID and ModelName are 1-to-1, you're good.
(Btw, your "distinct" here is superfluous - Select distinct a,b,c from tbl is simply shorthand for Select a,b,c from tbl group by a,b,c)

You have an identity column in the model_table, but you don't appear to be using it in the query where you check the ModelQuantity field. Don't you want to do something like this?
select ModelQuantity
from Model_table
where id = ##identity
?

First of all, you don't need the DISTINCT there, so you can get rid of it. And then, you can try this:
SELECT ID, ModelName, SUM(ModelQuantity) Quantity
FROM Model_Tabl
GROUP BY ID, ModelName
Ok, as I explained on my comment, if you have multiple IDs with the same name, you need to choose one, either the max or the min ID (it still doesn't make sense that you are going to end up just choosing one ID when you actually need to identify that ID), but well, here it is:
SELECT MIN(ID) ID, ModelName, SUM(ModelQuantity) Quantity
FROM Model_Tabl
GROUP BY ModelName

Related

How to I return a case record with latest date using SQL

I want a query that returns a record set of the shaded rows from the table above for each unique case_id by the latest data_level_assinged value. I tried something like this:
SELECT case_id, level, date_level_assigned
FROM table
SORT BY case_id, date_level_assigned DESC;
From reading it looks like I need to use an aggregate function like MAX(data_level_assinged) but am not sure how to do this.
You're almost there.
Using MAX is a good approach.
SELECT b.case_id, a.level, b.date_level_assigned FROM tablename a
JOIN
( SELECT MAX(date_level_assigned) as date_level_assigned, case_id
FROM tablename
GROUP BY case_id
) as b
ON a.case_id = b.case_id AND a.date_level_assigned = b.date_level_assigned
You can do it in this way

Query to show all ID's except the ones that have a specific instrument

So I have a table which looks like this:
What would be the best query to exclude every "stuknr" that has atleast 1 "saxofoon" in the "instrumentnaam" column?
To select all stuknr where there is not stuknr with a saxofoon:
SELECT *
FROM table
WHERE stuknr not in (
SELECT stuknr
FROM TABLE
WHERE INSTRUMENTNAAM = ‘saxofoon’)
;
SELECT STUNKR
FROM TABLE
WHERE INSTRUMENTNAAM != ‘saxofoon’;
Here != (or <>, which are equivalent, see this) means "not equal".
You can do this with a NOT IN sub-select
select distinct
YT.stunkr
from
YourTable YT
where YT.stunkr NOT IN ( select distinct stunkr
from YourTable
where InstrumentNaam = 'saxofoon' )
So the sub-select is getting all IDs that DO have saxofoon and the primary select/from is getting where the ID is NOT in the secondary.

Dynamic sorting by column depending on value in column

Plain and simple: Is it possible to create a dynamic ordering by system, depending on the value inside the column, the query will query.
The query goes something like this:
SELECT id, name, sortbycolumn FROM table
WHERE id = :in_id
UNION
SELECT id, name, null sortbycolumn FROM table
WHERE id = :in_id
ORDER BY -- This part I simply don't know how to write. I have tried case and decode...
To answer. I did finally find the solution. It was quite simple and whilst I read through other answers, I was confused as to why it did not work for me. Apparently the index of a column will not work when using case when.
In the end, I put up the whole query with unions into a subquery with the solution being:
SELECT * FROM(
SELECT id, name, sortbycolumn FROM table
WHERE id = :in_id
UNION
SELECT id, name, null sortbycolumn FROM table
WHERE id = :in_id
)
ORDER BY
case when sortbycolumn = 1 THEN id,
case when sortbycolumn = 2 then name
else id end

removing non-matching rows based on order in SQL within a WITH statement

I've got a many-to-many setup where there are items and item names(based on languageID)
I want to retrieve all names for a set id, where the name is replace with an alternate name (same itemID, but different languageID) when name is NULL.
I've set up a table that receives all combinations of itemids and itemnames, even the missing ones, and have the name ordered by an hasName flag, that is set based on name existing to 0,1 or 2. 0 means languageId and name exist, 1 means only name exists, and 2 means neither. I then sort the results: ORDER BY itemId, hasName, languageId this works well enough, because the top 1 row of every itemid meats the critera, and I can just pull that.
However I still need to process other queries using the result, so this doesn't work well, because as soon as I use a WITH statement, the order cannot be used, so it breaks the functionality
What I'm using instead is a join, where I select the top 1 matching row on the ordered table
the problem there is that the time to execute goes up 10x
any ideas what else I could try?
using SQL server 10.50
the slow query:
SELECT
*,
(SELECT top 1 ItemName FROM ItemNameMultiLang x WHERE x.ItemId = tc.ItemId ORDER BY ItemID, hasName, LangID) AS ItemName
FROM ItemCategories tc
ORDER BY ItemId
One way to approach this is with row_number(), so you can get the first row from itemNameMultiLang, which is what you want:
SELECT tc.*, inml.ItemName
FROM ItemCategories tc left outer join
(select inml.*, row_number() over (partition by inml.ItemId order by hasname, langId) as seqnum
from ItemNameMultiLang
) inml
on tc.ItemItem = inml.ItemId and
inml.seqnum = 1
ORDER BY tc.ItemId;

I need a sql query to group by name but return other fields based on the most recent entry

I'm querying a single table called PhoneCallNotes. The caller FirstName, LastName and DOB are recorded for each call as well as many other fields including a unique ID for the call (PhoneNoteID) but no unique ID for the caller.
My requirement is to return a list of callers with duplicates removed along with the PhoneNoteID, etc from their most recent entry.
I can get the list of users I want using a Group By on name, DOB and Max(CreatedOn) but how do I include uniqueID (of the most recent entry in the results?)
select O.CallerFName,O.CallerLName,O.CallerDOB,Max(O.CreatedOn)
from [dbo].[PhoneCallNotes] as O
where O.CallerLName like 'Public'
group by O.CallerFName,O.CallerLName,O.CallerDOB order by Max(O.CreatedOn)
Results:
John Public 4/4/2001 4/6/12 16:42
Joe Public 4/12/1988 4/6/12 16:52
John Public 1/2/1950 4/6/12 17:01
Thanks
You can also write what Andrey wrote somewhat more compactly if you select TOP (1) WITH TIES and put the ROW_NUMBER() expression in the ORDER BY clause:
SELECT TOP (1) WITH TIES
CallerFName,
CallerLName,
CallerDOB,
CreatedOn,
PhoneNoteID
FROM [dbo].[PhoneCallNotes]
WHERE CallerLName = 'Public'
ORDER BY ROW_NUMBER() OVER(
PARTITION BY CallerFName, CallerLName, CallerDOB
ORDER BY CreatedOn DESC
)
(By the way, there's no reason to use LIKE for a simple string comparison.)
Try something like that:
;WITH CTE AS (
SELECT
O.CallerFName,
O.CallerLName,
O.CallerDOB,
O.CreatedOn,
PhoneNoteID,
ROW_NUMBER() OVER(PARTITION BY O.CallerFName, O.CallerLName, O.CallerDOB ORDER BY O.CreatedOn DESC) AS rn
FROM [dbo].[PhoneCallNotes] AS O
WHERE
O.CallerLName LIKE 'Public'
)
SELECT
CallerFName,
CallerLName,
CallerDOB,
CreatedOn,
PhoneNoteID
FROM CTE
WHERE rn = 1
ORDER BY
CreatedOn
Assuming that the set of [FirstName, LastName, DateOfBirth] are unique (#shudder#), I believe the following should work, on pretty much every major RDBMS:
SELECT a.callerFName, a.callerLName, a.callerDOB, a.createdOn, a.phoneNoteId
FROM phoneCallNotes as a
LEFT JOIN phoneCallNotes as b
ON b.callerFName = a.callerFName
AND b.callerLName = a.callerLName
AND b.callerDOB = a.callerDOB
AND b.createdOn > a.createdOn
WHERE a.callerLName LIKE 'Public'
AND b.phoneNoteId IS NULL
Basically, the query is looking for every phone-call-note for a particular name/dob combination, where there is not a more-recent row (b is null). If you have two rows with the same create time, you'll get duplicate rows, though.