SQL: combining two sql queries - sql

I have two tables:
T_CHAMBRE_CHB (CHB_NUM);
T_PLANNING_PLN (PLN_JOUR ,CHB_NUM, PLN_LIBRE);
I have these values in it:
T_CHAMBRE_CHB:
1
2
3
4
T_PLANNIG_CHB:
1 2000-01-12 1 False
2 2000-01-12 2 False
3 2000-01-13 1 False
4 2000-01-13 2 False
5 2000-01-13 4 True
I would like to get the rooms occpation the 13 janvier 2000 for information if a room is not in the planning (here 3) that's mean it's free, so the result should be:
CHB_NUM PLN_LIBRE
----------- ---------
1 False
2 False
3 True
4 True
I have this query:
SELECT DISTINCT TCC.CHB_NUM, TPP.PLN_LIBRE
FROM T_CHAMBRE_CHB AS TCC,
T_PLANNING_PLN AS TPP
WHERE TCC.CHB_NUM=TPP.CHB_NUM AND TPP.PLN_JOUR = '2000-01-13'
UNION
SELECT DISTINCT TCC.CHB_NUM, TPP.PLN_LIBRE
FROM T_CHAMBRE_CHB AS TCC,
T_PLANNING_PLN AS TPP
WHERE TCC.CHB_NUM NOT IN (SELECT DISTINCT (TPP2.CHB_NUM) FROM T_PLANNING_PLN AS TPP2);
I get this result:
1 1 False
2 2 False
3 3 False
4 3 True
5 4 True
I don't know why I get the third line ( 3---->False )
I think I should use an OUTER UNION but SQL Server doesn't like the syntax.

Below query might give the required result :-
declare #date as date='2000-01-13'
select distinct TCC.CHB_NUM,COALESCE(TPP.PLN_JOUR,#date) PLN_JOUR,COALESCE(TPP.PLN_LIBRE,'True') PLN_LIBRE
from T_CHAMBRE_CHB TCC
LEFT OUTER JOIN
T_PLANNING_PLN TPP ON TCC.CHB_NUM=TPP.CHB_NUM
WHERE TPP.PLN_JOUR=#date OR TPP.PLN_JOUR IS NULL
Output :-
CHB_NUM PLN_JOUR PLN_LIBRE
1 2000-01-13 False
2 2000-01-13 False
3 2000-01-13 True
4 2000-01-13 True

You have to use left join if I am understanding your question.
Please use below query may be it helps you
SELECT T_CHAMBRE_CHB.CHB_NUM, ISNULL(T_PLANNIG_CHB.PLN_LIBRE, FALSE)
FROM T_CHAMBRE_CHB
LEFT JOIN T_PLANNIG_CHB ON (T_CHAMBRE_CHB.CHB_NUM = T_PLANNIG_CHB.CHB_NUM)
WHERE T_PLANNIG_CHB.PLN_JOUR = '2000-01-13'

Related

Tables with a ManyToOne relationship, how to select rows from master if none of the linked rows fulfill a condition?

I have two tables:
foos:
id
f_name
1
xxx
2
yyy
3
zzz
foo_bars:
id
foo_id
active
1
1
false
2
1
false
3
1
false
4
2
true
5
2
false
6
2
true
7
3
false
7
3
true
Each foo should have each an active foo_bar, and only one. Because of a poorly designed process, it sometimes happened that either more than one foo_bar was set to active=true, or that no foo_bar was set to active. Neither is a valid scenario.
I need to find those rows on foos where the linked foo_bars rows with active are != 1.
E.g. in the above scenario I'd like to get:
1,xxx
2,yyy
Can I accomplish this with a single query?
I think this would be a good use of the HAVING clause in a GROUP BY query:
select
f.id, f.f_name
from foos f
left join foo_bars b on f.id = b.foo_id
group by
f.id, f.f_name
having
count (*) filter (where b.active) != 1

MS Access merge two tables

I need to create a new table base on two tables. I have a database in ms access and need to migrate.
tableT tableS
ID CustID DATE Exp1 Exp2 ID CustID DATE Tem1 Tem2
-------------------------------- ---------------------------------
1 1 1/1/00 5 5 1 1 1/1/00 3 4
2 2 1/1/00 1 3 2 2 1/1/00 5 0
3 1 3/1/00 3 2 3 1 5/1/00 0 3
4 3 4/1/00 4 1 4 3 6/1/00 0 0
Desired output table tableNew:
ID CustID DATE Exp1 Exp2 Tem1 Tem2
---------------------------------------------
1 1 1/1/00 5 5 3 4
2 2 1/1/00 1 3 5 0
3 1 3/1/00 3 2
4 3 4/1/00 4 1
5 1 5/1/00 0 3
6 3 6/1/00 0 0
If I use outer join, I will not get the output I need.
Any idea or help.
You want a full join. You can emulate this in MS Access using:
select t.CustID, t.DATE, t.Exp1, t.Exp2, s.tem1, s.tem2
from TableT as t left outer join
tableS as s
on t.CustId = s.CustId and t.date = s.date
union all
select s.CustID, s.DATE, null, null, s.tem1, s.tem2
from tableS as s left outer join
tableT as t
on t.CustId = s.CustId and t.date = s.date
where t.CustId is null;

Group by clause with count() and where condition in subquery

Table : Class
id Institute_id Name
------------------------------
1 1 MCAL - 1
2 1 MCAL - 2
3 1 BCA - 1
4 1 BCA - 2
Table : Groups
id Class_Id Institute_Id Name Status
--------------------------------------------------
1 1 1 PHP false
2 2 1 JAVA false
3 1 1 ORACLE false
4 2 1 LINUX true
5 2 1 ASP.NET false
6 3 1 OS false
7 4 2 CPP false
Expected Result :
id Name Count(*)
-----------------------------
1 MCAL - 1 2
2 MCAL - 2 2
3 BCA - 1 1
4 BCA - 2 0
Note: count only those records from Groups where Institute_Id = 1 and Status=false
Please try this
Select
c.id,
c.name,
SUM(case when g.class_id is NULL then 0 else 1 end) as count
from class c left join groups g
on c.id=g.class_id
and g.status='false'
and g.Institute_id=1
group by c.id,c.name
order by c.id
fiddle link: http://sqlfiddle.com/#!6/2b992/6
To count properly with outer joins, specify the column name instead of * in COUNT().
SELECT C.id, C.Name, [Count] = COUNT(G.Status)
FROM Class C
LEFT JOIN Groups G ON C.id = G.Class_id AND G.Institute_id = 1 AND G.Status = 'false'
GROUP BY C.id, C.Name
ORDER BY C.id

sql server count distinct value of a field

I have 2 tables : Contents and Packs
In Content columns are like this:
Id Name IsPerishable IsSpecial IsDanger
----------------------------------------------------------
1 Paper False False False
3 Fruit True False False
5 NewsPaper False True False
6 Radioactive False False True
7 Foods True False False
In Packs columns are like this:
Id From To ContentId
---------------------------------------
1 ABZ ATL 3
2 ANU ATL 5
3 BAQ ATL 7
4 BTS BAQ 6
5 FRL BAQ 5
Now I want a result that groups every 'To' then shows separate value of IsPerishable / IsSpecial / IsDanger
like this:
To Perishable Special Danger
-----------------------------------------------
ATL 2 1 0
BAQ 0 1 1
I try use some query but none of them has worked correctly:
select Name,
case
when IsSpecial = 1 then count(IsSpecial)
when IsPerishable = 1 then count(IsPerishable)
when IsDanger = 1 then count(IsDanger)
end as 'Content'
from Contents
group by IsSpecial , IsPerishable , IsDanger
select To,count(DISTINCt Id) as 'Count'
FROM Packs
GROUP BY To
try this
Select To,
(Select count(*) from Content c where c.Id= p.Id and c.IsSpecial=1) as Special,
(Select count(*) from Content c where c.Id= p.Id and c.Isperishable=1) as Perishable,
(Select count(*) from Content c where c.Id= p.Id and c.Isperishable=1) as Danger
from
pack p
group by To
SELECT P.To, SUM(Perishable), SUM(Special),SUM(Danger) FROM
(
SELECT Id,
CASE IsPerishable WHEN true THEN 1 ELSE 0 END AS Perishable,
CASE IsSpecial WHEN true then 1 ELSE 0 END AS Special,
CASE IsDanger WHEN true then 1 ELSE 0 END AS Danger
FROM Contents
) C
Right Join Packs P
on P.ContentId=C.Id
Group BY P.to

Value carry forword

I have below SQL Query..
SELECT dbo.O3.[s.no] AS [O3_Sn.NO], dbo.O5.[s.no] AS [O5_Sn.NO], dbo.O3.O3, dbo.O5.O5,
case when dbo.O3.[s.no] > dbo.O5.[s.no] then 'true' else 'false' end as ComparisonColumn
FROM dbo.O3 INNER JOIN
dbo.O5 ON dbo.O3.[s.no] = dbo.O5.[s.no]
When I run I am getting below output..
O3_Sn.NO O5_Sn.NO O3 O5 ComparisonColumn
1 1 10 11 TRUE
2 2 12 13 TRUE
3 3 11 10 FALSE
4 4 13 11 FALSE
5 5 15 16 TRUE
6 6 10 11 TRUE
7 7 12 13 TRUE
I want to remember the value of TRUE / False and should ignore if it is repeated untill i get a reverse case i.e., for TRUE , False.. and FOR False .. TRUE
Below is the out i should get it..
O3_Sn.NO O5_Sn.NO O3 O5 ComparisonColumn New_Case_Carry_value
1 1 10 11 TRUE TRUE
2 2 12 13 TRUE NULL
3 3 11 10 FALSE FALSE
4 4 13 11 FALSE NULL
5 5 15 16 TRUE TRUE
6 6 10 11 TRUE NULL
7 7 12 13 TRUE NULL
You can order your output using row_number() to compare a value with a value of the previous record:
with cIntermediate as (
SELECT dbo.O3.[s.no] AS [O3_Sn.NO], dbo.O5.[s.no] AS [O5_Sn.NO], dbo.O3.O3, dbo.O5.O5,
case when dbo.O3.[s.no] > dbo.O5.[s.no] then 'true' else 'false' end
as ComparisonColumn,
rowno = row_number() over
(order by dbo.O3.[s.no], dbo.O5.[s.no], dbo.O3.O3, dbo.O5.O5)
FROM dbo.O3 INNER JOIN dbo.O5 ON dbo.O3.[s.no] = dbo.O5.[s.no]
)
select i1.*,
case when i1.ComparisonColumn = i2.ComparisonColumn then null
else i1.ComparisonColumn end as NewCaseCarryValue
from cIntermediate i1
left join cIntermediate i2 on i2.rowno=i1.rowno-1
Ok, I will explain the concept to you, and I am sure you will be able to figure it out for yourself.
Your final result you published with all the true and false columns, that needs to become a temporary table, like this, but with some kind of identity column:
SELECT dbo.o3.[s.no] AS [O3_Sn.NO]
,dbo.o5.[s.no] AS [O5_Sn.NO]
,dbo.o3.o3
,dbo.o5.o5
,CASE
WHEN dbo.o3.[s.no] > dbo.o5.[s.no] THEN 'true'
ELSE 'false'
END AS comparisoncolumn
, ROW_NUMBER() OVER(ORDER BY dbo.o3.[s.no]) AS ident_col
INTO #temp
FROM dbo.o3
INNER JOIN dbo.o5
ON dbo.o3.[s.no] = dbo.o5.[s.no]
Then what you need to do is to select from #temp, and self join to #temp in a similar manner as here:
SELECT a.*
, CASE WHEN a.comparisoncolumn = b.comparisoncolumn THEN NULL ELSE a.comparisoncolumn END AS final_comparisoncolumn
FROM #temp a
LEFT JOIN #temp b ON a.ident_col = b.ident_col - 1
Then do a case statement to figure out if you need to print null, or true or false.
Play around with this concept, I am sure you will be able to work it out from here.
You can do an left join on the table itself (SN = SN-1) and compare the ComparisonColumn