Sql select with grouping rows - sql

In mssql-db I have a table with 5 columns.
id, 1st_t1, 1st_t2, 2nd_t1, 2nd_t2
it's single "task" with 2 parameters(t1,t2) "grouped" by person type(1st,2nd)
Is it possible to select info like this on picture in Reporting Service?:
Or the only way is divide this table on two tables for each person type?

In your report, your detail must have two rows.
On the first you will drag and drop the data of the 1st person and on the second row for the second like in the image below

Please try below query:
WITH T(ID, First_t1, First_t2, Second_t1, Second_t2)
AS
(
SELECT *
FROM
(
SELECT 1 ID, '1st_t1' First_t1, '1st_t2' First_t2, '2nd_t1' Second_t1, '2nd_t2' Second_t2
UNION
SELECT 2 ID, '1st_t1' First_t1, '1st_t2' First_t2, '2nd_t1' Second_t1, '2nd_t2' Second_t2
UNION
SELECT 3 ID, '1st_t1' First_t1, '1st_t2' First_t2, '2nd_t1' Second_t1, '2nd_t2' Second_t2
) A
)
SELECT * FROM
(
SELECT '1st person' person, Id,First_t1 t1,First_t2 t2 FROM T
union
SELECT '2nd person' person, Id,Second_t1 t1,Second_t2 t2 FROM T
) B
ORDER BY id

Related

2 sql queries 2 different results using UNION

I have 2 queries that start with same tables but filter different columns. Both queries are unioned together so I can get a single count of people without duplication.
If I run the queries with the union commented out I have the same number of rows in each 1,953. When I run with the union I get 1,816 in one and 1,922 in the other.
My data is just an account # like 123456 in the first column and a 1/0 in the second column. Help me understand how this can happen if I am starting with the same number of rows.
Here is one of the queries
select distinct acct#,
case
when (lastFilledDate is not null and lastFilledDate<>'00/00/00') or
([Last Filled DC] is not null and [Last Filled DC]<>'00/00/00') or
(vivitrol is not null and vivitrol <>'00/00/00') or
(sublocade is not null and sublocade <>'00/00/00') or
(naltrexone is not null and naltrexone <>'00/00/00') then 1
else 0 end as result
from
(
select Acct#, DOB, [COE Contact Note], [COE-INTAKA Doc], [COE-MOM
Doc], lastFilledDate, [Last Filled DC],vivitrol,sublocade,naltrexone,
ROW_NUMBER() over (partition by Acct# order by [COE-INTAKA Doc] desc)
as apptRows
from tblAppBSCImportDashCOE2279 as main
where (([COE-MOM Doc]='Yes' and [COE Contact Note] is not null) or
[COE-MOM Doc]='No') and Appt is not null
) as sub
where apptRows=1
union
select distinct acctNo,
case
when
providerMAT='The Wright Center' and [COE-MOM Doc] is not null then
1
else 0
end as result
from
(
select acctNo, [COE-MOM Doc], MAT, providerMAT,
ROW_NUMBER() over (partition by acctNo order by COEBNMOM, [COE-MOM Doc]
desc) as apptRows
from tblAppBSCImportDashCOEHM2544 as main
where [COE-MOM Doc] is not null or COEBNMOM is not null
) as sub
where apptRows=1
results look like
acct# result
123456 1
234567 0
There is one possibility. The records you selected may result in duplicate records WITHIN each select statement. Let me try to illustrate with an example. (you can input the following query into your session to follow along)
IF OBJECT_ID('TEMPDB..#TEMP1') IS NOT NULL
DROP TABLE #TEMP1
IF OBJECT_ID('TEMPDB..#TEMP2') IS NOT NULL
DROP TABLE #TEMP2
CREATE TABLE #TEMP1(
id INT
,account INT
,amount INT
,yes_no INT
)
INSERT INTO #TEMP1 (id,account,amount,yes_no)
VALUES(1,123456,5,0)
,(2,123456,10,0)
,(3,123456,20,0)
CREATE TABLE #TEMP2(
id INT
,account INT
,amount INT
,yes_no INT
)
INSERT INTO #TEMP2 (id,account,amount,yes_no)
VALUES(4,123456,5,0)
,(5,123456,10,0)
,(6,123456,20,0)
SELECT *
FROM #TEMP1
SELECT *
FROM #TEMP2
Output of this is 2 tables with distinct records:
Now suppose I write queries that select account and the 'yes_no' column:
SELECT account,yes_no
FROM #TEMP1
SELECT account,yes_no
FROM #TEMP2
You can see that now all of the records are the same values within each select statement. So what do you think happens when I union these queries together?
SELECT account,yes_no
FROM #TEMP1
UNION
SELECT account,yes_no
FROM #TEMP2
UNION will output the distinct values of the ENTIRE OUTPUT, which also applies within each query. This is an extreme example of what I think you are experiencing. You need to include some sort of ID for each query such that it can be distinguished from other records within the query, like;
SELECT id,account,yes_no
FROM #TEMP1
UNION
SELECT id,account,yes_no
FROM #TEMP2

find the count from 2 tables

I want to find this count but when I execute the query it seems like it is stucked to "waiting for the query to complete" forever...any ideas?
SELECT (
SELECT COUNT(*)
FROM accidents,"Vechicles"
where "Date_of_accident"<'2010-01-01' and "Urban_or_Rural" like 'Urban' and "Age_Band_Of_Driver" like '26 - 35'
) AS count1
Because your query will select every row from the first table that matches your criteria, then for each row it will then select EVERY row from the second table that matches your criteria. This might end up being a huge number of rows that end up selected.
Here's an example:
CREATE TABLE #dumb (id INT);
CREATE TABLE #dumber (id INT);
INSERT INTO #dumb SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3;
INSERT INTO #dumber SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3;
SELECT * FROM #dumb, #dumber;
3 rows in each table, but the query selects 3 * 3 = 9 rows. Now imagine that there's 3 million rows in each table!

Matching a substring to a string

Please advise me on the following question:
I have two tables in an Oracle db, one that contains full numbers and the other that contains parts of them.
Table 1:
12323543451123
66542123345345
16654232423423
12534456353451
64565463345231
34534512312312
43534534534533
Table 2:
1232
6654212
166
1253445635
6456546
34534
435345
Could you please suggest a query that joins these two tables and shows the relation between 6456546 and 64565463345231, for example. The main thing is that Table 2 contains a lot more data than Table 1, and i need to find all the substrings from Table 2 that are not present in Table 1.
Thanks in advance!
Try this:
with t as (
select 123 id from dual union all
select 567 id from dual union all
select 891 id from dual
), t2 as (
select 1112323 id from dual union all
select 32567321 id from dual union all
select 44891555 id from dual
)
select t.id, t2.id
from t, t2
where t2.id||'' like '%'||t.id||'%'
You could try using the CONTAINS operator like this :
SELECT * FROM Table2 JOIN Table1 ON Table1.id=Table2.id
WHERE NOT CONTAINS (Table2.data, Table1.data)
Are numbers from table two in a set place in table 1? For example is the 1232 in the same place each time or do you have to search a sting for the numbers. If it's set you could use an inline select or a temp table and create a substring of the string your searching and then join the table or temp table on that field.
you first need to say if the number in Table 1 and 2 are repeated, if is not then I think this query would help you:
SELECT *
FROM Table_1
JOIN Table_2 ON Table_1.ID = Table_2.ID
WHERE Table_2.DATA LIKE Table_1.DATA

find the missing values from a set of values, using SQL

How can I find a missing values from a set of values, using SQL (Oracle DB)
e.g.
SELECT NAME
FROM ACCOUNT
WHERE ACCOUNT.NAME IN ('FORD','HYUNDAI','TOYOTA','BMW'...)
(The "IN" clause may contain hundreds of values)
If 'HYUNDAI' is missing in the ACCOUNT table, I need to get the result as "HYUNDAI".
Currently I use the result of the above query to do a Vlookup against the original set of values to find the missing values, I want to directly get the missing values without doing the Vlookup.
Thanks
Kiran,
You got it reversed. Do this: http://www.sqlfiddle.com/#!2/09239/3
SELECT Brand
FROM
(
-- Oracle can't make a row without a table, need to use DUAL dummy table
select 'FORD' as Brand from dual union
select 'HYUNDAI' from dual union
select 'TOYOTA' fom dual union
select 'BMW' from dual
) x
where Brand not in (select BrandName from account)
Sample Account data:
create table account(AccountId int, BrandName varchar(10));
insert into account(AccountId, BrandName) values
(1,'FORD'),
(2,'TOYOTA'),
(3,'BMW');
Output:
| BRAND |
-----------
| HYUNDAI |
Better yet, materialized the brands to a table:
select *
from Brand
where BrandName not in (select BrandName from account)
Output:
| BRANDNAME |
-------------
| HYUNDAI |
Sample data and live test: http://www.sqlfiddle.com/#!2/09239/1
CREATE TABLE Brand
(`BrandName` varchar(7));
INSERT INTO Brand
(`BrandName`)
VALUES
('FORD'),
('HYUNDAI'),
('TOYOTA'),
('BMW');
create table account(AccountId int, BrandName varchar(10));
insert into account(AccountId, BrandName) values
(1,'FORD'),
(2,'TOYOTA'),
(3,'BMW');
You should use Except: EXCEPT returns any distinct values from the left query that are not also found on the right query.
WITH SomeRows(datacol) --It will look for missing stuff here
AS( SELECT *
FROM ( VALUES ('FORD'),
('TOYOTA'),
('BMW')
) AS F (datacol)),
AllRows (datacol) --This has everthing
AS( SELECT *
FROM ( VALUES ('FORD'),
('HYUNDAI'),
('TOYOTA'),
('BMW')
) AS F (datacol))
SELECT datacol
FROM AllRows
EXCEPT
SELECT datacol
FROM SomeRows
You can do:
SELECT a.val
FROM
(
SELECT 'FORD' val UNION ALL
SELECT 'HYUNDAI' UNION ALL
SELECT 'TOYOTA' UNION ALL
SELECT 'BMW' UNION ALL
etc...
etc...
) a
LEFT JOIN account b ON a.val = b.name
WHERE b.name IS NULL
This worked perfectly, thanks Michael.
SELECT Brand
FROM
( -- Oracle can't make a row without a table, need to use DUAL dummy table
select 'FORD' as Brand from dual union
select 'HYUNDAI' from dual union
select 'TOYOTA' fom dual union
select 'BMW' from dual
)
where Brand not in (select BrandName from account)
Luxspes and Zane thank you for your inputs
Contributing Excel code to make the typing of the answer easier:
Say column A has the values (Ford, Hyundai,...).
In column B, put this in every cell:
select 'x' as brand from dual union
In column C, write this formula, and copy it down.
=REPLACE(A2,9,1,A1)
All of the select/union statements should appear in column C.

create view for items not in list

I have two tables. Table 1 is a master list of equipment with equipment_id and equipment_description. So, let's say for this table I have ten equipment_id's. 1,2,3....10 each with some description attached.
Table 2 logs when the equipment has been inspected:
equipment_id|inspection_date
1 | '1-22-2012'
2 | '1-22-2012'
4 | '1-22-2012'
2 | '1-23-2012'
3 | '1-23-2012'
I've created a view, v_dates which pulls out of table 2 all of the distinct inspection dates - not sure if I needed it but did it anyway.
I would like to create another view which shows all equipment that was NOT inspected for each date in the v_dates. So it would show:
3 | '1-22-2012'
5 | '1-22-2012'
and so on.
Rookie here and just not sure how to join these tables correctly. Can't get it to work and would appreciate any help.
Untested, but I think this should give the desired result:
SELECT i.id,d.date FROM
( SELECT DISTINCT inspection_date AS date FROM inspections ORDER BY 1 ) d
LEFT JOIN
inspections i
ON d.date=i.date
WHERE i.date IS NULL
GROUP BY 1,2
ORDER BY 1,2
Like mentioned in the comments would a table with inspection dates really help.
The following appears to work based on my test data using SQL SERVER 2005. I am using a CROSS JOIN of distinct dates along with a LEFT JOIN to throw out EQUIPMENT_ID records that exist for those dates.
Sorry, I am having problems getting my code formatting correct with tabs and spaces...
IF OBJECT_ID('tempdb..#EQUIPMENT') IS NOT NULL
DROP TABLE #EQUIPMENT
CREATE TABLE #EQUIPMENT
( EQUIPMENT_ID smallint,
EQUIPMENT_DESC varchar(32)
)
INSERT INTO #EQUIPMENT
( EQUIPMENT_ID, EQUIPMENT_DESC )
SELECT 1, 'AAA'
UNION SELECT 2, 'BBB'
UNION SELECT 3, 'CCC'
UNION SELECT 4, 'DDD'
UNION SELECT 5, 'EEE'
UNION SELECT 6, 'FFF'
UNION SELECT 7, 'GGG'
UNION SELECT 8, 'HHH'
UNION SELECT 9, 'III'
UNION SELECT 10, 'JJJ'
IF OBJECT_ID('tempdb..#INSPECTION') IS NOT NULL
DROP TABLE #INSPECTION
CREATE TABLE #INSPECTION
( EQUIPMENT_ID smallint,
INSPECTION_DATE smalldatetime
)
INSERT INTO #INSPECTION
( EQUIPMENT_ID, INSPECTION_DATE )
SELECT 1, '1-22-2012'
UNION SELECT 1, '1-27-2012'
UNION SELECT 3, '1-27-2012'
UNION SELECT 5, '1-29-2012'
UNION SELECT 7, '1-22-2012'
UNION SELECT 7, '1-27-2012'
UNION SELECT 7, '1-29-2012'
SELECT E.EQUIPMENT_ID, D.INSPECTION_DATE
FROM #EQUIPMENT E
CROSS JOIN ( SELECT DISTINCT INSPECTION_DATE
FROM #INSPECTION
) D
LEFT JOIN #INSPECTION I2
ON E.EQUIPMENT_ID = I2.EQUIPMENT_ID
AND D.INSPECTION_DATE = I2.INSPECTION_DATE
WHERE I2.EQUIPMENT_ID IS NULL
ORDER BY E.EQUIPMENT_ID, D.INSPECTION_DATE
As per my comment to the question, you really need a table of valid inspection dates. It makes the sql much more sensible, and besides it's the only way to do it if you want to see all items listed for dates when inspections were supposed to be done, but no inspections were done.
So, assuming the two tables:
create table inspections (equipment_id int, inspection_date date);
create table inspection_dates (id int, inspection_date date);
Then a join to get all the equipment that does not have an inspection on a date when an inspection should have taken place would be:
select i.equipment_id, id.inspection_date
from inspection_dates id,
(select distinct equipment_id from inspections) i
where not exists (select * from inspections i2
where i2.inspection_date = id.inspection_date
and i2.equipment_id = i.equipment_id);
You want the combos that do not exist. Thus the not exists predicate.
Note again, that presumably you would have a table for all the unique equipment_ids, but not knowing that I had to construct it myself in place.