Multiple selection from SQL Table - sql

I am trying to write a query to return multiple matching results,I want to see how many record match a column from a table.
select [pomDocumentId],
[svPartNo],
count(svPartNo) as dup
from [tbl_ODW_PomItem]
group by [svPartNo],[pomDocumentId]
I tried this,but won't work. I am trying to see how many [pomDocumentId] matches a [svPartNo] in the table.
Thank you.
id pomDocumentId svPartNo
4955 8298 5WK96132-E
6131 14826 5WK96132-E
Here is the query that solved the problem:
select [svPartNo], count(svPartNo) as dup
from [ODW_Dev].[dbo].[tbl_ODW_PomItem]
group by [svPartNo]
having count(svPartNo)>1
order by dup desc

Seems like you're after a simple GROUP BY with COUNT, run the below SQL to test with your sample data:
DECLARE #tbl_ODW_PomItem AS TABLE
([id] int, [pomDocumentId] int, [svPartNo] varchar(10))
;
INSERT INTO #tbl_ODW_PomItem
([id], [pomDocumentId], [svPartNo])
VALUES
(4955, 8298, '5WK96132-E'),
(6131, 14826, '5WK96132-E')
;
SELECT COUNT(pomDocumentId) DocCount, svPartNo
FROM #tbl_ODW_PomItem
GROUP BY svPartNo
This produces:
DocCount svPartNo
======================
2 5WK96132-E

Try the below code.
SELECT svPartNo, COUNT(pomDocumentId) FROM TAB GROUP BY svPartNo

Related

SQL aggregate values and add new columns

I am having some trouble to aggregate data on row-inputs. I have two columns originally, but i want to split the data based on PortID and add five columns which now lie in the AssetClass column as row values.
The first table is how the data is structured now, the second is what i want it to look like.
Anyone have any tips how to do this? Thanks in advance.
You basically need to pivot your data set. Below query will pivot you data set purely using UNION and GROUP BY Clause which will be supported by any database system. You can add your pivot asset class S,U,P inside set_union block as done for C,F
Alternatively, you can simply use PIVOT operator.
CREATE TABLE sample
(
id int,
port_id nvarchar(10),
percent_weight int,
asset_class nvarchar(1)
);
INSERT INTO sample values
('1','SOL','15','C'),
('2','EID','20','C'),
('3','PAR','25','C'),
('45','SOL','30','F'),
('46','EID','40','F'),
('47','PAR','45','F')
;
SELECT
port_id,
MAX(C) AS C,
MAX(F) AS F
FROM
(
SELECT
id,
port_id,
percent_weight AS C,
NULL AS F
FROM
sample
WHERE
asset_class='C'
UNION
SELECT
id,
port_id,
NULL AS C,
percent_weight AS F
FROM
sample
WHERE
asset_class='F'
)set_union
GROUP BY
port_id
ORDER BY
id ASC;
Output:

Error - INSERT has more expressions than target columns

I am trying to insert the number_of orders into storiacloud.schl_storia_school_status_try.The calculations are done in another table (storiacloud.vw_storia_oms_orders). The promblem is that it is trying to insert school_ucn as well but i am just using that for group by and do not want to insert that. Can somebody please help
INSERT INTO storiacloud.schl_storia_school_status_try
(no_of_orders)
select school_ucn,count(otc_order_number)
from storiacloud.vw_storia_oms_orders
group by school_ucn;
You can just remove it from the select:
INSERT INTO storiacloud.schl_storia_school_status_try (no_of_orders)
select count(otc_order_number)
from storiacloud.vw_storia_oms_orders
group by school_ucn;
It will still group, just not report it. I'm not sure what use a bunch of random numbers in a table is though.
... or add the missing column in the INSERT's list of columns:
INSERT INTO storiacloud.schl_storia_school_status_try
(no_of_orders, [YOUR_NB_ORDER_COLUMN] )
select school_ucn,count(otc_order_number)
from storiacloud.vw_storia_oms_orders
group by school_ucn;

Sql server order by value not by field name

suppose my table structure is like
ID OEReference
--- ------------
1 00000634B9
2 00000634B6
3 0005000053
4 0002855071
5 0000940148
6 0001414825
7 00000634B9
i want that they way i supply OEReference that order should maintain in output.
my sql is like
Select * from mytable where OEReference in ('00000634B9','0001414825','00000634B6')
the above statement did not return resultset according to the order of IN clause. i know that it is not possible by ORDER BY CLAUSE
how can i do it with simple sql statement in sql server. thanks
You could use a temporary table as a filter. Aninner join will enforce the filter, and you can sort on the identity column:
declare #filter table (id int identity, ref varchar(50))
insert #filter values ('00000634B9')
insert #filter values ('0001414825')
insert #filter values ('00000634B6')
select *
from YourTable yt
join #filter filter
on filter.ref = yt.OEReference
order by
filter.id
Please here is my solution for you:
SELECT [id], [OEReference]
FROM [Tbl]
where [OEReference] in ('002', '001')
order by case [OEReference]
when '002' then 1
when '001' then 2
end
Please note: this can decrease performance of your server. It depends on how many rows in table you have. However, you can easily add index for OEReference. Off course, you should generate such query dynamically.
My solution is not close ideal. Maybe you found it useful for you.
Happy coding!

T-SQL Output Clause: How to access the old Identity ID

I have a T-SQL statement that basically does an insert and OUTPUTs some of the inserted values to a table variable for later processing.
Is there a way for me to store the old Identity ID of the selected records into my table variable. If I use the code below, I get "The multi-part identifier "a.ID" could not be bound." error.
DECLARE #act_map_matrix table(new_act_id INT, old_ID int)
DECLARE #new_script_id int
SET #new_script_id = 1
INSERT INTO Act
(ScriptID, Number, SubNumber, SortOrder, Title, IsDeleted)
OUTPUT inserted.ID, a.ID INTO #act_map_matrix
SELECT
#new_scriptID, a.Number, a.SubNumber, a.SortOrder, a.Title, a.IsDeleted
FROM Act a WHERE a.ScriptID = 2
Thanks!
I was having your same problem and found a solution at http://sqlblog.com/blogs/adam_machanic/archive/2009/08/24/dr-output-or-how-i-learned-to-stop-worrying-and-love-the-merge.aspx
Basically it hacks the MERGE command to use that for insert so you can access a source field in the OUTPUT clause that wasn't inserted.
MERGE INTO people AS tgt
USING #data AS src ON
1=0 --Never match
WHEN NOT MATCHED THEN
INSERT
(
name,
current_salary
)
VALUES
(
src.name,
src.salary
)
OUTPUT
src.input_surrogate,
inserted.person_id
INTO #surrogate_map;
You'll have to join back #act_map_matrix onto Act to get the "old" value.
It's simply not available in the INSERT statement
edit: one hopes that #new_scriptID and "scriptid=2" could be the join column

Looking for SQL constraint: SELECT COUNT(*) from tBoss < 2

I'd like to limit the entries in a table. Let's say in table tBoss. Is there a SQL constraint that checks how many tuples are currently in the table? Like
SELECT COUNT(*) from tBoss < 2
Firebird says:
Invalid token.
Dynamic SQL Error.
SQL error code = -104.
Token unknown - line 3, column 8.
SELECT.
You could do this with a check constraint and a scalar function. Here's how I built a sample.
First, create a table:
CREATE TABLE MyTable
(
MyTableId int not null identity(1,1)
,MyName varchar(100) not null
)
Then create a function for that table. (You could maybe add the row count limit as a parameters if you want more flexibility.)
CREATE FUNCTION dbo.MyTableRowCount()
RETURNS int
AS
BEGIN
DECLARE #HowMany int
SELECT #HowMany = count(*)
from MyTable
RETURN #HowMany
END
Now add a check constraint using this function to the table
ALTER TABLE MyTable
add constraint CK_MyTable__TwoRowsMax
check (dbo.MyTableRowCount() < 3)
And test it:
INSERT MyTable (MyName) values ('Row one')
INSERT MyTable (MyName) values ('Row two')
INSERT MyTable (MyName) values ('Row three')
INSERT MyTable (MyName) values ('Row four')
A disadvantage is that every time you insert to the table, you have to run the function and perform a table scan... but so what, the table (with clustered index) occupies two pages max. The real disadvantage is that it looks kind of goofy... but everything looks goofy when you don't understand why it has to be that way.
(The trigger solution would work, but I like to avoid triggers whenever possible.)
Does your database have triggers? If so, Add a trigger that rolls back any insert that would add more than 2 rows...
Create Trigger MyTrigName
For Insert On tBoss
As
If (Select Count(*) From tBoss) > 2
RollBack Transaction
but to answer your question directly, the predicate you want is to just put the select subquery inside parentheses. like this ...
[First part of sql statement ]
Where (SELECT COUNT(*) from tBoss) < 2
To find multiples in a database your best bet is a sub-query for example: (Note I am assuming you are looking to find duplicated rows of some sort)
SELECT id FROM tBoss WHERE id IN ( SELECT id FROM tBoss GROUP BY id HAVING count(*) > 1 )
where id is the possibly duplicated column
SELECT COUNT(*) FROM tBoss WHERE someField < 2 GROUP BY someUniqueField