SQL requery same table - sql

I have a table that has a bunch of information:
Part Number, Category, Value, FreqL, FreqH, FREQ1, FREQ2.
I am trying to filter based on a user entry... Say they put in Part Number "xzy"
SELECT backup.Value, backup.FREQ1, backup.FREQ2
FROM backup
WHERE ((backup.[Part Number]) ="xyz";
I want to requery the table, but also include parts that fit all the same values resulting from xyz query.
I thought of using IN before my subquery, but that only limits to one column, how do i do all three?
Of course the below isn't working >
SELECT backup.[Part Number], backup.Value, backup.FreqL, backup.FreqH
FROM backup
WHERE (backup.Value AND backup.FREQ1 AND Backup.FREQ2) (
SELECT backup.Value, backup.FREQ1, backup.FREQ2, backup.CAT
FROM backup
WHERE ((backup.[Part Number]) ="xyz")
);
Any help is appreciated.
Thank you.
JR

I guess you need below query -
SELECT B1.[Part Number], B1.Value, B1.FreqL, B1.FreqH
FROM backup B1
JOIN (SELECT Value, FREQ1 , FREQ2
FROM backup
WHERE [Part Number] ="xyz") B2 ON B1.Value = B2.Value
AND B1.FREQ1 = B2.FREQ1
AND B1.FREQ2 = B2.FREQ2;

A typical method uses exists:
SELECT b.[Part Number], b.Value, b.FreqL, b.FreqH
FROM backup b
WHERE EXISTS (SELECT 1
FROM backup b2
WHERE b2.[Part Number] = 'xyz' AND
b2.Value = b.Value AND
b2.FREQ1 = b.FREQ1 AND
b2.FREQ2 = b.FREQ2
);

You don't say your platform, in DB2 tuples work -- like this:
SELECT backup.[Part Number], backup.Value, backup.FreqL, backup.FreqH
FROM backup
WHERE (backup.Value, backup.FREQ1, Backup.FREQ2) = (
SELECT backup.Value, backup.FREQ1, backup.FREQ2
FROM backup
WHERE ((backup.[Part Number]) ="xyz")
);

Related

Selecting additional data/values to display as column in query or in form

I have an employee index, that I need to run queries on for each employee, and display that output along with the original employee.
So say the employee index has an ID, batch, status, and multiple other columns. I have a table where I keep track of every time a column in the employee index changes. I want to display and later export dates of when certain columns use to equal other values, right along side the original employee row.
Naturally I tried creating a form to display multiple value, added a text box to hold my extra information, and changed the value of the text box for each Form_Current event in VBA.
Private Sub Form_Current()
Me.txtPhaseOne = SimpleLookup("SELECT TOP 1 ChangeDate FROM EmployeeVariables WHERE VariableName = ""Batch"" AND EmployeeID = " & Me.Recordset("ID Number") & " ORDER BY ChangeDate ASC", "ChangeDate")
End Sub
It seemed to work at first...
Until I realized the dates were set to whatever the current record date should be
[
So then I tried a join:
SELECT
EmployeeIndex.[ID Number],
EmployeeIndex.Batch,
EmployeeIndex.Status,
EmployeeIndex.[First name],
EmployeeIndex.[Last name],
EVA.ChangeDate as Phase1
FROM
EmployeeIndex
(SELECT TOP 1 ChangeDate FROM EmployeeVariables WHERE EmployeeID = EmployeeIndex.[ID Number] ORDER BY CHangeDate) EVA
Which would work, if I could some how prefetch EmployeeIndex.[ID Number]. (I didn't name these columns) Except I haven't got the slightest clue and I'm running on fumes.
SELECT
EmployeeIndex.[ID Number],
EmployeeIndex.Batch,
EmployeeIndex.Status,
EmployeeIndex.[First name],
EmployeeIndex.[Last name],
EVA.ChangeDate as Phase1
FROM
EmployeeIndex
INNER JOIN
(SELECT TOP 1 EmployeeID, ChangeDate FROM EmployeeVariables WHERE ORDER BY ChangeDate) EVA
ON EmployeeIndex.[ID Number] = EVA.EmployeeID
Try with a subquery:
SELECT
EmployeeIndex.[ID Number],
EmployeeIndex.Batch,
EmployeeIndex.Status,
EmployeeIndex.[First name],
EmployeeIndex.[Last name],
(SELECT Max(EVA.ChangeDate)
FROM EmployeeVariables AS EVA
WHERE EVA.EmployeeID = EmployeeIndex.[ID Number]) AS Phase1
FROM
EmployeeIndex
Cross Apply will be perfect for your TOP 1 case, as it will run for each employeeID rather than just joining on 1

Microsoft Access adding an extra column to existing union select

[enter image description here][1]I need to add 4 columns ( Item name, FullPrice_2018(price), FullPrice_2019(price), (FullPrice_2019-FullPrice_2018) ) to the query. I can't figure out how to add another column to the union without merging rows.
Right now my table is with 2018 & 2019 items but I need 3 more columns.
https://i.stack.imgur.com/lTmqB.png
SELECT FullPrice_2018.[Item name]
FROM FullPrice_2018
UNION
SELECT FullPrice_2019.[Item name]
FROM FullPrice_2019
ORDER BY [Item name]
Result should be like this
"Item name" price2018 price2019 "price2019-price2018"
https://i.stack.imgur.com/XxKU5.png
Do you just want JOIN:
SELECT F2018.[Item name], F2018.FullPrice, F2019.FullPrice,
(F2019.FullPrice - F2018.FullPrice)
FROM FullPrice_2018 as F2018 INNER JOIN
FullPrice_2019 as F2019
ON F2018.[Item name] = F2019.[Item name]
ORDER BY F2018.[Item name];
Unfortunately, MS Access doesn't support FULL JOIN. But I think you can do:
SELECT [Item name], MAX(FullPrice_2018), MAX(FullPrice_2019),
(MAX(FullPrice_2019) - MAX(FullPrice_2018))
FROM (SELECT F2018.[Item name], F2018.FullPrice as FullPrice_2018, NULL as FullPrice_2010
FROM FullPrice_2018 as F2018
UNION ALL
SELECT F2019.[Item name], NULL, F2019.FullPrice as FullPrice_2019
FROM FullPrice_2019 as F2019
) F
GROUP BY [Item name]
ORDER BY [Item name];
Not all versions of MS Access support UNION ALL in the FROM clause, so you might need to use a view for that portion of the query.
Create a query that will return a normalised output:
SELECT
FullPrice_2018.[Item name], 2018 As [Year], Price
FROM
FullPrice_2018
UNION ALL
SELECT
FullPrice_2019.[Item name], 2019 As [Year], Price
FROM
FullPrice_2019
Save the query and use it as source in a normal crosstab query. Use the wizard to create this if you are unfamiliar with crosstab queries.

Asking to enter a parameter value that already exists

I have a three column table of price breaks called "FPB" that looks like this:
[Part Number] [Quantity] [Price]
AAA-AAAA     100   1.23
AAA-AAAA     200   1.15
BBB-BBBB     100   5.60
CCC-CCCC      500   3.21
....
Where each part number has multiple entries in multiple rows.
I'm trying to reorganize the table to look more like this
[Part Number] [Quantity1] [Price 1] [Quantity 2] [Price 2] [Quantity 3....
AAA-AAAA      100   1.23    200    1.15   ....
BBB-BBBB      100   5.60     ...
CCC-CCCC       500   3.21    ...
...
Where each part number has all its entries combined into one row. The first quantity column should have the lowest available quantity, the second should have the second smallest etc. I am trying to do this by first creating a 1-column table with just the unique part numbers using GROUP BY, and then creating more tables for each column that has the information I want in that column, and then joining it by Part Number. The problem comes when calculating the second smallest quantity for each type, done in the second to last section.
SELECT PNs.[Part Number], Q1T.Q1, P1T.Price, Q2T.Q2
FROM
(SELECT
[Part Number]
FROM FPB
GROUP BY [Part Number]
) AS PNs,
(SELECT
[Part Number],
MIN(Quantity) AS Q1
FROM FPB
GROUP BY [Part Number]
) AS Q1T,
(SELECT
*
FROM FPB
) AS P1T,
(SELECT
[Part Number],
MIN(IIF(Quantity>Q1T.Q1,Quantity)) AS Q2
FROM FPB
GROUP BY [Part Number]
) AS Q2T
WHERE
PNs.[Part Number] = Q1T.[Part Number]
AND P1T.[Part Number] = PNs.[Part Number]
AND P1T.Quantity = Q1T.Q1
AND Q2T.[Part Number] = PNs.[Part Number]
When I run this query, it asks me to enter a parameter value for Q1T.Q1, even though it already exists. If I remove the code section for Q2T, as well as any references to Q2, it will work without a problem, and it won't ask about a value for the other instances of Q1T.Q1. Why doesn't Q1T.Q1 have a value just for that section, and how can I fix it? As a side note, I'm using the SQL features of a program called PHPRunner, and its client doesn't support UPDATE/DELETE/INSERT/CREATE queries, UNION, and DISTINCT.
You're looking for something like this.
select
p1.PartNumber,
ifnull(max(p2.Quantity), 0) + 1 as LowerQuantity,
p1.Quantity as UpperQuantity,
p1.Price,
count(p2.PartNumber) + 1 as PriceTier
from
FPB p1 left outer join FPB p2
on p2.PartNumber = p1.PartNumber and p2.Quantity < p1.Quantity
From there it's easy to pivot in order to insert into a new table:
into into NewFPB (PartNumber, Quantity1, Price1, Quantity2, Price2, ...)
select
PartNumber,
min(switch(PriceTier = 1, UpperQuantity)) as Quantity1,
min(switch(PriceTier = 2, UpperQuantity)) as Quantity2, ...
min(switch(PriceTier = 1, Price)) as Price1,
min(switch(PriceTier = 2, Price)) as Price2, ...
from (
select
p1.PartNumber,
ifnull(max(p2.Quantity), 0) + 1 as LowerQuantity,
p1.Quantity as UpperQuantity,
p1.Price,
count(p2.PartNumber) + 1 as PriceTier
from
FPB p1 left outer join FPB p2
on p2.PartNumber = p1.PartNumber and p2.Quantity < p1.Quantity
) data
You might have to tweak it a little bit for Access to accept it. But the core ideas are there.
The query you call is incorrect.
Q1T is inner select statement , and in Q2T (other inner select statement) , you can't use any field from Q1T
The SQL Server raise error: Incorrect syntax near ')'.
To overcome this limitation , you should use Common Table Expressions CTE
for PNs, Q1T, P1T, Q2T
CTE is like dynamic view.
It's a new feature since sql 2008 and It's a very powerful.
review: https://technet.microsoft.com/en-us/library/ms190766(v=sql.105).aspx
Try to Draw a relational data model for these four CTE to be sure that a relation exist between them based on your where conditions.
I think the logic in this query may raise runtime error during execution:
e.g. The multi-part identifier "Q1T.Q1" could not be bound.
Edit:
For Ms-Access you can create four queries for: PNs, Q1T, P1T, Q2T every one is in a separate query, and the fifth query join these queries and add where conditions.
In this case you will not get any syntax error. and will get Data model with relation free :) .
As per your question, by the time you define the derived table Q2T, Q1T is still an invalid object. You need to try to work around this issue.
EDIT:
Suppose you only got 2-level columns to handle, the code is listed below, i tested it. It works well.
select q5.*,q3.quantity, q3.price
from
(select *
from FPB as Q1
where 0 = (select count(distinct(quantity)) from FPB as Q2 where Q2.quantity < Q1.quantity AND Q2.[part number] = Q1.[part number])) as Q5
,
(
select distinct(temp.[part number]),Q2.quantity, Q2.price from FPB as temp
left join
(select *
from FPB as Q4
where 1 = (select count(distinct(quantity)) from #test as Q2 where Q2.quantity < Q4.quantity AND Q2.[PART NUMBER] = Q4.[PART NUMBER])) as Q2
on temp.[PART NUMBER] = Q2.[PART NUMBER]
) as Q3
where Q5.[PART NUMBER] = Q3.[PART NUMBER]

SQL exclude all rows that with have certain value?

i have a table with these value, and here is a small sample
order state item id
10064315 ON MCM1L162L116
10064315 ON MCM1R162R116
10064315 ON SHIPPING
10064316 MS 00801-1778
10064316 MS SHIPPING
10064317 AZ CHM110439-1
10064317 AZ SHIPPING
10064318 TX 2607
10064318 TX SHIPPING
10064319 MO CHG8080
10064319 MO SHIPPING
10064322 CA W10001130
I want to write a sql query that only list on the order number that without SHIPPING, in this sample, the only one without SHIPPING would be 10064322.
I try to find in here but didn't find what I am looking for.
Thank for the help
SELECT DISTINCT [order]
FROM MYTABLE
WHERE [order] not in (SELECT [order]
FROM MYTABLE
WHERE [item id] = 'SHIPPING')
EDIT:
According to Aaron Bertrand's article (hat tip #TTeeple in the comments) the best performance for this problem (needing the distinct) is done as follows:
SELECT [order]
FROM MYTABLE
EXCEPT
SELECT [order]
FROM MYTABLE
WHERE [item id] = 'SHIPPING'
For the full article -> http://sqlperformance.com/2012/12/t-sql-queries/left-anti-semi-join
One option is to use not exists:
select ordernumber
from yourtable y
where not exists (
select 1
from yourtable y2
where y.ordernumber = y2.ordernumber and y2.itemid = 'SHIPPING'
)
Use conditional aggregation:
select [order] from
table
group by [order]
having sum(case when [item id] = 'SHIPPING' then 1 else 0 end) = 0

Need to do tthis in 1 SQL

I have to process in an sql as follows. each order is made up of many detail rows. I only need to look at one table, TRA99.
Order number TRAN CODE
123 QEE
123 #23
123 ABC
SELECT
ALL OTRIDC, OTCOM#, OTORD#, OTFL50, OTTRND, OTTRT, OTENT#,
OTSFX#,
OTREL#, OTUSRN, OTTRNC, OTTRN$, OTFL01
FROM ASTDTA.OETRANOT T01
WHERE OTTRNC IN ('QEE', 'QNE')
I want all the Order # which have 'QEE' or 'QNE'. These are QUote codes. We want a report that will tell us, which quotes orders' converted to a real order and which did not.
then if they have as well #23, this tells me that the order was converted or became an actual order. I am not sure how to do this in 1 sql query i was thinking to create a view for all QEE and QNE codes. then run a second query against that looking for #23.
Based on what I think you're trying to do. This will give you all the order numbers which are associated with both QEE or QNE and #23
SELECT T1.OrderNumber
FROM TRA99 T1
WHERE T1.OrderNumber in (
SELECT OrderNumber
FROM TRA99
WHERE TCode IN ('QEE','QNE')
)
AND T1.TCode='#23'
GROUP BY T1.OrderNumber
What you need to do is use a GROUP BY also a EXISTS sub-query can check for the existence of your flag
select t1.[Order Number]
,(CASE WHEN EXISTS(select *
from TRA99 as t2
where t1.[Order Number] = t2.[Order Number]
and t2.[Tran Code] = '#23')
THEN
cast(1 as bit)
ELSE
cast(0 as bit)
END) as HasFlag
from TRA99 as t1
where t1.[Tran Code] in ('QFE', 'QNE')
group by t1.[Order Number]
Working example
NOTE: you did not list what DBMS you are using so I wrote this against Microsoft Sql Server syntax, but you can translate this concept to any DBMS you need.