I have two tables:
Table A 'Real Orders':
Contract,
Order ID,
YYYYMM
Table B 'Uploads':
Contract,
Order ID,
YYYYMM
I want to make a query with the following structure:
Contract, YYYYMM, Nb of Real Orders, Nb of Uploads
How can I accomplish that knowing that some contracts from Table A don't appear in Table B and vice-versa? I am use SQL Server 2012.
I tried splitting the code into two sub queries, let me know if this works..
select coalesce(a.contract,b.contract) as contract,
coalesce(a.YYYYMM,b.YYYYMM) as YYYYMM,
no_real_orders,
no_uploads
from
(
select contract,YYYYMM, count (order_id) as no_real_orders,
from Table_a
group by contract, YYYYMM
) as a
full join
(
select contract,YYYYMM, count (order_id) as no_uploads,
from Table_b
group by contract, YYYYMM
) as b
on a.contract = b.contract
and a.YYYYMM = b.YYYYMM
Let me know if this works
select coalesce( a.contract,b.contract) as contract,
coalesce(a.YYYYMM,b.YYYYMM) as YYYYMM,
count (a.order_id) as no_real_orders,
count (b.order_id) as no_uploads
from Table_a as a
full join Table_b as b
on a.contract = b.contract
and a.YYYYMM = b.YYYYMM
group by coalesce(a.contract,b.contract), coalesce(a.YYYYMM,b.YYYYMM)
Unfortunately, I get the same count for both columns. Here is an excerpt from the output:
Contract YYYYMM Nb Real Orders Nb Uploads
Contract_x 201701 17 17
Contract_x 201612 72 72
Contract_y 201702 196 196
Contract_y 201612 345 345
Contract_y 201701 264 264
The code is:
select coalesce(a.Contract_Code,b.Contract_Code) as Contract,
coalesce(a.OIA_Creation_Date_YYYYMM,b.Ordear_Creation_YYYYMM) as
YearMonth, count(a.OIA_Order_Number) as Nb_Real_Orders,
count(b.Order_Number) as Nb_Uploads from Raw_Data_A as a full join
Raw_Data_B as b on a.Contract_Code=b.Contract_Code and
a.OIA_Creation_Date_YYYYMM=b.Ordear_Creation_YYYYMM group by
coalesce(a.Contract_Code,b.Contract_Code),coalesce(a.OIA_Creation_Date_YYYYMM,b.Ordear_Creation_YYYYMM)
Related
I have the two joined tables below. I'd like to get only the one line from the REQUIREMENTS table with the most recent date (3/8/2019).
**PART** **REQUIREMENTS**
ID OH TIME PART ORDER QTY DATE
5512 5 21 5512 74619 102 3/8/2019
5512 74907 25 3/10/2019
5512 74908 41 3/19/2019
5512 74243 59 3/21/2019
When I use Min(REQUIREMENTS.DATE), I still get all four rows because of the unique data in both the ORDER and QTY tables. I'm pretty sure I need to use Select Top 1 [...] but I'm having trouble figuring out where to use it. Ultimately I'm looking to return:
PART DATE OH TIME ORDER QTY
5512 3/8/2019 5 21 74619 102
Can anyone point me in the right direction (SQL Server 2012)? Thanks in advance!
Dan
You can use a correlated subquery to do this:
SELECT *
FROM PART P
INNER JOIN REQUIREMENTS R ON
P.ID = R.PART
WHERE REQUIREMENTS.[DATE] = (SELECT MAX([DATE] FROM REQUIREMENTS WHERE R.PART = PART)
You can use APPLY, your choice if you want OUTER or CROSS.
SELECT p.ID, p.state, p.time
, r.qty, r.date1
FROM dbo.Part p
OUTER APPLY (
select top 1 qty, date
from dbo.Requirements
where part = p.ID
order by date1
) as r
I have a temp table that contains the following data:
The WV1 column needs to be updated to the department value for all rows that share the same date for example;
WV1 = 19176 for all 2017-11-08 00:00:00.000 rows
WV1 = 18067 for all 2017-11-06 00:00:00.000 rows
The WV1 column may remain as NULL if there is no 215 code but it doesn't matter for my purposes, I can't create other temp tables meaning I'm restricted to CTE or subqueries, thanks in advance for any help!
You can use the following using CTE:
;WITH CTE AS
(SELECT IDNO, [DATE], DEPARTMENT
FROM #TAB
WHERE CODE = 215
)
UPDATE T
SET WV1 = C.DEPARTMENT
FROM #TAB T
JOIN CTE C ON C.IDNO = T.IDNO AND C.[DATE] = T.[DATE]
Thanks.
I output invoices that are made up of info in two separate data tables linked by a unique ID #. I need to update the service provided in a group of invoices (service info contained in table_B) for only a certain date period (date info contained in table_A).
Here's the two tables I am joining
Table_A
ID------|Name-----------------|Date----------|Total--------|
1-------|--ABC Company--------|--1/1/17------|--$50--------|
2-------|--John Smith---------|--3/1/17------|--$240-------|
3-------|--Mary Jones---------|--2/1/16------|--$320-------|
1-------|--ABC Company--------|--8/1/16------|--$500-------|
Table_B
Table_ID (= ID Table_A)----|-Service-----------|Unit Price--|Qty------|
1--------------------------|--Service A--------|--$50.00----|--10-----|
--
2--------------------------|--Service B--------|--$20.00----|--12-----|
--
3--------------------------|--Service B--------|--$20.00----|--16-----|
--
1--------------------------|--Service A--------|--$50.00----|--10-----|
I am able to join the two tables using:
Select * from Table_B b inner join Table_A a on b.Table_ID = a.ID
which results in following:
Results
Table_ID-|-Service-----|-Unit Price-|-Qty-|-ID--|-Name-----|-Date----|Total--|
1--------|-Service A- |$50.00------|-10--|-1---|-ABC Co.--|-1/1/17--|$500--|
2--------|-Service B- |$20.00------|-12--|-2---|-John S.--|-3/1/17--|$240--|
3--------|-Service B- |$20.00------|-16--|-3---|-Mary J.--|-2/1/16--|$320--|
1--------|-Service A- |&50.00------|-10--|-1---|-ABC Co.--|-8/1/16--|$500--|
Now, I want only rows that are for dates greater 12/31/16. However, when I add a where clause for the date (see below) my results don't change.
Select * from Table_B b inner join Table_A a on b.Table_ID = a.ID where date > 12/31/16
I would expect just two rows for services on 1/1/17 and 3/1/17. How can I filter for just rows with a particular date value in this newly joined table?
Assuming your date is contained in a column intended for storing dates, and not string, try making sure that the date you're passing in really is being interpreted as a date:
SELECT
*
FROM
table_b b
INNER JOIN
table_a a
on b.Table_ID = a.ID
WHERE
a.date > CONVERT(datetime , '20161231' , 112 )
I suspect that SQLSERVER is interpreting your date 12/31/16 as "twelve divided by thirty one divided by sixteen" - a floating point number approximately 0.0241935
The way dates are handled, internally, they are convertable to floating point numbers representing the number (and fraction of) days since a certain point in time, I believe 1 Jan 1900. Hence your 0.024 floating point number will represent a date about 35 minutes past midnight on 01 jan 1900.. and that's why your results aren't filtering, because all the dates satisfy the where clause (theyre all later than 01-01-1900 00:35)!
What result are you getting with your current implementation, because I don't see any issue with your current query
Please test below script, it may give you expected output.
Select *
from Table_B b
inner join Table_A a
on b.Table_ID = a.ID
and date > convert(date , '20161231' , 112 )
Select *
from Table_B b
inner join Table_A a
on b.Table_ID = a.ID
where date > '12/31/16'
Can you try to use the quotes with your date.
Or best way is to use
Select *
from Table_B b
inner join Table_A a
on b.Table_ID = a.ID
where Date BETWEEN '12/31/2016' and '1/1/2018'
My question is very basic as it deals with two tables: reservations and events.
Table reservations contains 5 column which indicate the event type, this is a number.
For example:
table reservations
event_1 event_2 event_3 event_4 event_5
181 177 485 772 474
Table events contain the details about the event.
For example:
table events
id event_key location
181 8888512 10
177 2255998 88
485 7895201 12
772 1212855 22
474 2125495 10
I would like to be able to write a query to which I will provide an event_key, and using the id from the table events, get to the reservations table.
I have a limited knowledge of using joins, or sub-queries, I can get the idea with some explanation and help but I am unsure as to what method will get me the results I need. I hope that through this question I can get a bit of good help.
Thank you.
UPDATE
This is the type of query I was thinking of:
SELECT
e.[id],
e.[event_key],
e.[event_location],
e.[event_room],
e.[event_description],
e.[event_instructor],
r.[reservation_id],
r.[guest_first_name],
r.[guest_last_name],
r.[guest_age],
r.[guest_city],
et-cetera...
FROM events e
LEFT JOIN reservations r
ON e.id IN (r.event_1, r.event_2, r.event_3, r.event_4, r.event_5)
WHERE e.event_key IN ('8888512', '7895201', '2125495')
If you want to determine if event is event_1, event_2 and so on, you need to UNPIVOT the reservation table and JOIN it with the event table:
DECLARE #event_key INT = 2125495;
WITH CteUnpivotReservations(event_id, event_type) AS(
SELECT event_1, 'event_1' FROM reservations UNION ALL
SELECT event_2, 'event_2' FROM reservations UNION ALL
SELECT event_3, 'event_3' FROM reservations UNION ALL
SELECT event_4, 'event_4' FROM reservations UNION ALL
SELECT event_5, 'event_5' FROM reservations
)
SELECT
r.*
FROM CteUnpivotReservations r
INNER JOIN event e
ON r.event_id = e.id
WHERE
e.event_key = #event_key
SQL Fiddle
I have two tables
table-a
id name
100 asd
101 ass
102 gdd
103 hgf
104 cvd
105 erf
table-b
id filter
100 red
101 blue
100 green
100 yellow
102 black
102 red
103 dark
Table-a is the master table and that have all the id's.but Table two is the one which has 'filter' data.
from these two table I want to find out all those 'id's which does not have minimum 2 filters.
note that table-b does not have all the itemnumbers in table-a, and i want all that itemnumber irrespective of if that is in table-a or table-b.I have tried inner joining these two tables and getting data out but nothing worked.
Select A.ID, A.Name, count(*)
from tableA A
LEFT JOIN tableB B on A.ID = B.ID
Group By A.ID, A.name
having count(*) <= 1
LEFT JOIN gives all records from A and only those in B which match.
The group by ID and name let us count the number of filters found in
each
The having says give me any items with a count less than or
equal to 1. (or less than the minimum 2)
Thus results would be.
101 ass 1
103 hgf 1
104 cvd 0
105 erf 0
select
*
from
table-a a
left join (
select id, count(id) as c from table-b group by id
) v on a.id = v.id
where isnull(v.id, 0) < 2
I think this would work in SQL Server (tested in SQLite and usually the two are fairly compatible when it comes to inline view syntax). But syntax issues aside, inline views can make working with sets easier to visualize.
select TA.id, name
from TA
inner join
(
select id from TA
where not exists (select id from TB where TA.id = TB.id)
UNION
select id from TB
group by id having count(filter) < 2
) as FOO
on TA.id = FOO.id
The default behavior of UNION is to remove duplicates.
The first UNIONed set consists of the ids from table A that have no filter (no counterpart in the filters table B).
The second UNIONed set consists of the ids from the filters table, table B, that have only 1 filter.
We inner join those unioned sets back to Table A to get the entity Name.