I have following table:
Query 1 works fine and returns both records
select *
from dbo.PersonalAttribute
where ProductId = '12345'
Query 2-3-4-5 works fine and filters on AttributeType and corresponding AttributeDescription.
select *
from dbo.PersonalAttribute
where ProductId = '12345'
and (AttributeType = 'test1' and AttributeDescription = 0) -- will return one row
select *
from dbo.PersonalAttribute
where ProductId = '12345'
and (AttributeType = 'test1' and AttributeDescription = 1) -- will return zero rows
select *
from dbo.PersonalAttribute
where ProductId = '12345'
and (AttributeType = 'test2' and AttributeDescription = 1) -- will return one row
select *
from dbo.PersonalAttribute
where ProductId = '12345'
and (AttributeType = 'test1' and AttributeDescription = 0) -- will return zero rows
Query 6 not working and returns 0 rows even all conditions are true:
select *
from dbo.PersonalAttribute
where ProductId = '12345'
and (AttributeType = 'test1' and AttributeDescription = 0)
and (AttributeType = 'test2' and AttributeDescription = 1)
How can I rewrite Query 6 to have an ability to filter data by combination of vales in Attricute Type and Attribute Description columns, basically I need to select only when both conditions are true and if both conditions are not true no rows should be returned.
Thank you!
The "and" means you are looking at the same row for two different things. You are allowed to pick up one fruit. You cannot pick up an apple and a pear. But you can pick up an apple or a pear. Change that "and" to "or" and wrap it in parenthesis:
select *
from dbo.PersonalAttribute
where ProductId = '12345'
and ((AttributeType = 'test1' and AttributeDescription = 0)
or (AttributeType = 'test2' and AttributeDescription = 1))
One option is via a JOIN. You can create a Temp table or even a Table Variable to hold the desired combinations
select P.*
From dbo.PersonalAttribute P
Join ( values ('test1',0)
,('test2',1)
) V(AttrT,AttrD)
on AttributeType = AttrT
and AttributeDescription = AttrD
and ProductId = '12345'
I have a Array of Struct field containing values like- field_name= [1,2,3,4]
I want to identify rows where field_name NOT contains values 2 OR 3 in BigQuery
Sample Data: Assume I have 4 rows of data:
row_id = 1 , field_name = [1,2,3,4]
row_id = 2 , field_name = [1,2]
row_id = 3 , field_name = [3,4]
row_id = 4 , field_name = [4]
What I want- Expected Result: row_id = 4 , field_name = [4]
I tried with UNNEST and EXISTS, UNNEST gives output as row_id = 1, row_id = 2, row_id = 3 & row_id = 4
Consider below approach
select * from your_table t
where not exists (
select value
from t.field_name as value
where value in (2,3)
)
if applied to sample data in your question - output is
if you would use where value in (1,2) - output were
I'm running into a problem wherein I need to get the changes of an Employee based on specific conditions.
I should retrieve rows only based on the changes below:
Assignment Category (only based on specific Categories shown in the table xxtest)
Pay Basis (only from Hourly to Salaried and Vice Versa, also shown in the table xxtest)
Both Pay Basis and Assignment Category (based on the same constraints above)
I have created a Table (XXTEST) to restrict the SQL to only reference this mapping (See DML and DDL at the end of the Question).
Basically, the Data I'm Expecting would be:
| --------|-------------------|------------------|---------------|------------- |-------------|
| Sample | FROM_PAY_BASIS_ID | TO_PAY_BASIS_ID | FROM_CATEGORY | TO_CATEGORY | CHANGE_TYPE |
| --------| ------------------| -----------------| --------------|------------- |-------------|
| 1 | 1 | 2 | FR | FR | PAY_BASIS |
| 2 | 1 | 1 | FT | FR | ASSIGN_CAT |
| 3 | 1 | 2 | FT | FR | BOTH |
the table above is based on the conditions below:
1. if BOTH, it should get "Assignment Category and Pay Basis" as its Change_Type
2. if Assignment Category, it should get "Assignment Category" as its Change_Type
3. if Pay Basis, it should get "Pay Basis" as its Change_Type
I want it to evaluate first the condition 1, and if its false, then evaluate the next until the last.
the problem occurs when both of these columns change, resulting into having 3+ rows with CHANGE_TYPE having "PAY_BASIS", "ASSIGN_CAT", "BOTH" as values.
I've tried a lot of methods but nothing seemed to fully address my need, such as the query below:
select *
from (select coalesce((select CHANGE_TYPE
from XXTEST
where FROM_CATEGORY = pax.EMPLOYMENT_CATEGORY
AND TO_CATEGORY = pax2.EMPLOYMENT_CATEGORY
AND FROM_ID = pax.PAY_BASIS_ID
and TO_ID = pax2.PAY_BASIS_ID),
select CHANGE_TYPE
from XXTEST
WHERE FROM_CATEGORY = pax.EMPLOYMENT_CATEGORY
AND TO_CATEGORY = pax2.EMPLOYMENT_CATEGORY
AND FROM_ID = 0
and TO_ID = 0),
select CHANGE_TYPE
from XXTEST
WHERE FROM_CATEGORY = 'N/A'
AND TO_CATEGORY = 'N/A'
AND FROM_ID = pax.PAY_BASIS_ID
and TO_ID = pax2.PAY_BASIS_ID),
NULL ) CHANGE_TYPE FROM DUAL ) CHANGE_TYPE
, PPX.FULL_NAME
, PPX.EMPLOYEE_NUMBER
from per_people_X ppx
, per_assignments_X pax
, per_assignments_X pax2
WHERE pax.assignment_id = pax2.assignment_id
AND PPX.PERSON_id = pax2.PERSON_id
AND PPX.PERSON_id = PAX.PERSON_id)
where CHANGE_TYPE is not null;
This kinda works but it retrieves all records, regardless if it has a match or not (due to the NULL "else" condition) and results into Change_Type = NULL.
Is it possible to just filter only those records that do not have Change_Type = NULL without encasing it in another SELECT statement?
I've also tried using CASE,
It works fine if the Employee's Pay Basis ID only changed (ex. from 1 to 2)
and if only the Employee's Category has changed (ex. from FT to FR),
but it evaluates all the cases (returning 3 rows) whenever "both" changes occur.
Any advise?
I didn't follow all the details of your post and the answers and ensuing comments, but it seems you may be after something like this. To get exactly one answer in all situations, you probably need a CASE expression. In the code below I use nested CASE expressions, but that is only to save typing (and a little bit of execution time); you could rewrite this using a single CASE expression.
The reason this works is that evaluation ends immediately as soon as the first TRUE condition in the when... then... pairs is found. You will have to figure out how to attach this to your existing query - I just put its outputs in a CTE for testing purposes below.
with
query_output ( empl_id, from_pay_basis_id, to_pay_basis_id, from_category, to_category ) as (
select 101, 1, 2, 'FR', 'FR' from dual union all
select 102, 1, 1, 'FT', 'FR' from dual union all
select 103, 1, 2, 'FT', 'FR' from dual union all
select 104, 1, 1, 'FR', 'FR' from dual
)
select empl_id, from_pay_basis_id, to_pay_basis_id, from_category, to_category,
case when from_category != to_category then
case when from_pay_basis_id != to_pay_basis_id then 'Assignment Category and Pay Basis'
else 'Assignment Category'
end
when from_pay_basis_id != to_pay_basis_id then 'Pay Basis'
end as change_type
from query_output;
EMPL_ID FROM_PAY_BASIS_ID TO_PAY_BASIS_ID FROM_CATEGORY TO_CATEGORY CHANGE_TYPE
------- ----------------- --------------- ------------- ----------- ---------------------------------
101 1 2 FR FR Pay Basis
102 1 1 FT FR Assignment Category
103 1 2 FT FR Assignment Category and Pay Basis
104 1 1 FR FR
You are probably after case statements in the where clause, something like:
SELECT PPX.FULL_NAME
, PPX.EMPLOYEE_NUMBER
, XT.CHANGE_TYPE
FROM per_people_X ppx
, XXTEST XT
, per_assignments_X pax
, per_assignments_X pax2
WHERE pax.assignment_id = pax2.assignment_id
AND PPX.PERSON_id = pax2.PERSON_id
AND PPX.PERSON_id = PAX.PERSON_id
AND (-- Both Employment Category and Pay Basis records records that were Changed
case when XT.FROM_CATEGORY = pax.EMPLOYMENT_CATEGORY
AND XT.TO_CATEGORY = pax2.EMPLOYMENT_CATEGORY
AND XT.FROM_ID = pax.PAY_BASIS_ID
AND XT.TO_ID = pax2.PAY_BASIS_ID
then 1
else 0
end = 1
OR
-- all Pay Basis records that were "Updated"
case when XT.FROM_CATEGORY = 'N/A'
AND XT.TO_CATEGORY = 'N/A'
AND XT.FROM_ID = pax.PAY_BASIS_ID
AND XT.TO_ID = pax2.PAY_BASIS_ID
then 1
else 0
end = 1
OR
-- all Assignment Category records that were "Updated"
case when XT.FROM_CATEGORY = pax.EMPLOYMENT_CATEGORY
AND XT.TO_CATEGORY = pax2.EMPLOYMENT_CATEGORY
AND XT.FROM_ID = 0
AND XT.TO_ID = 0
then 1
else 0
end = 1);
N.B. untested, since you didn't provide sample data for the per_people_x or per_assignments tables.
You may have to add extra conditions into the "both categories" case expression to exclude the other two cases; it's not immediately apparent from the data that you have supplied so far.
First of all if you use OR you should use brackets and (... or ... ) or you lose some predicates. Your first query should be rewritten to:
SELECT PPX.FULL_NAME
, PPX.EMPLOYEE_NUMBER
, XT.CHANGE_TYPE
FROM per_people_X ppx
, XXTEST XT
, per_assignments_X pax
, per_assignments_X pax2
WHERE pax.assignment_id = pax2.assignment_id
AND PPX.PERSON_id = pax2.PERSON_id
AND PPX.PERSON_id = PAX.PERSON_id
-- THIS IS THE SECTION OF THE QUERY WHERE I'M HAVING PROBLEMS --
-- Both Employment Category and Pay Basis records records that were Changed
AND (
(XT.FROM_CATEGORY = pax.EMPLOYMENT_CATEGORY
AND XT.TO_CATEGORY = pax2.EMPLOYMENT_CATEGORY
AND XT.FROM_ID = pax.PAY_BASIS_ID
AND XT.TO_ID = pax2.PAY_BASIS_ID)
-- all Pay Basis records that were "Updated"
or (XT.FROM_CATEGORY = 'N/A'
AND XT.TO_CATEGORY = 'N/A'
AND XT.FROM_ID = pax.PAY_BASIS_ID
AND XT.TO_ID = pax2.PAY_BASIS_ID)
-- all Assignment Category records that were "Updated"
or (XT.FROM_CATEGORY = pax.EMPLOYMENT_CATEGORY
AND XT.TO_CATEGORY = pax2.EMPLOYMENT_CATEGORY
AND XT.FROM_ID = 0
AND XT.TO_ID = 0)
);
EDIT: Add solution with ranking of condition
SELECT FULL_NAME
, EMPLOYEE_NUMBER
, CHANGE_TYPE
FROM (
SELECT PPX.FULL_NAME
, PPX.EMPLOYEE_NUMBER
, XT.CHANGE_TYPE
, DENSE_RANK() OVER (PRTITION BY PPX.PERSON_id,pax.assignment_id ORDER BY
CASE WHEN XT.FROM_CATEGORY = pax.EMPLOYMENT_CATEGORY
AND XT.TO_CATEGORY = pax2.EMPLOYMENT_CATEGORY
AND XT.FROM_ID = pax.PAY_BASIS_ID
AND XT.TO_ID = pax2.PAY_BASIS_ID
THEN 1
WHEN XT.FROM_CATEGORY = 'N/A'
AND XT.TO_CATEGORY = 'N/A'
AND XT.FROM_ID = pax.PAY_BASIS_ID
AND XT.TO_ID = pax2.PAY_BASIS_ID
THEN 2
ELSE 3
END
) as RNK
FROM per_people_X ppx
, XXTEST XT
, per_assignments_X pax
, per_assignments_X pax2
WHERE pax.assignment_id = pax2.assignment_id
AND PPX.PERSON_id = pax2.PERSON_id
AND PPX.PERSON_id = PAX.PERSON_id
-- THIS IS THE SECTION OF THE QUERY WHERE I'M HAVING PROBLEMS --
-- Both Employment Category and Pay Basis records records that were Changed
AND (
(XT.FROM_CATEGORY = pax.EMPLOYMENT_CATEGORY
AND XT.TO_CATEGORY = pax2.EMPLOYMENT_CATEGORY
AND XT.FROM_ID = pax.PAY_BASIS_ID
AND XT.TO_ID = pax2.PAY_BASIS_ID)
-- all Pay Basis records that were "Updated"
or (XT.FROM_CATEGORY = 'N/A'
AND XT.TO_CATEGORY = 'N/A'
AND XT.FROM_ID = pax.PAY_BASIS_ID
AND XT.TO_ID = pax2.PAY_BASIS_ID)
-- all Assignment Category records that were "Updated"
or (XT.FROM_CATEGORY = pax.EMPLOYMENT_CATEGORY
AND XT.TO_CATEGORY = pax2.EMPLOYMENT_CATEGORY
AND XT.FROM_ID = 0
AND XT.TO_ID = 0)
)
) WHERE RNK = 1;
Here is my table in my Microsoft Access database:
Terr(Prim) Terr(Sec) Qty
---------- --------- -------
A A 0.5
A B 0.5
I want to change it to like this through SQL:
Type Terr Qty
----------- ---- ----
Original A 0.5
Original A 0.5
50-50 give A -0.5
50-50 take B 0.5
Rules:
Create two columns, [Type] and [Terr]
if [Terr(Prim)] = [Terr (Sec)], then keep the row and [Type] = "Original"
if [Terr (Prim)] <> [Terr (Sec)], then:
Row 1: [Type] = "Original", [Terr] = [Terr(Prim)], the other columns remain the same
Row 2: [Type] = "50-50 Give", [Terr] = [Terr (Prim)], [Qty] turns into negative
Row 3: [Type] = "50-50 take", [Terr] = [Terr (Sec)], the other columns remain the same
delete [Terr(Prim)] and [Terr (Sec)]
I think you can use a query like this:
SELECT "Original" As [Type], [TerrPrim] AS [Terr], Qty
FROM t
UNION ALL
SELECT "50-50 Give" As [Type], [TerrPrim] AS [Terr], -Qty
FROM t
WHERE [TerrPrim] <> [TerrSec]
UNION ALL
SELECT "50-50 take" As [Type], [TerrSec] AS Terr, Qty
FROM t
WHERE [TerrPrim] <> [TerrSec];
I'm making a stored procedure where I have declared a column with the AS "NameofColumn" method. Now I want to use that value again later in the stored procedure. Is there anyway to do this?
CASE
WHEN ((select top 1 stuksweergeven from componenten where componentid = componentlink.componentid) = 1) and ((select AmountKG from componenten where componentid = componentlink.componentid) <> 0) THEN
Amount * (select AmountKG from componenten where componentid = componentlink.componentid)
ELSE
Amount
END AS Amount
Now later I want to do the following
Amount * 10 AS TotalAmount
Use subquery where you count the "Amount" and then make select to from that subquery . Something like that:
select Amount * 10 AS TotalAmount from ( SELECT CASE
WHEN ((select top 1 stuksweergeven from componenten where componentid = componentlink.componentid) = 1) and ((select AmountKG from componenten where componentid = componentlink.componentid) <> 0) THEN
Amount * (select AmountKG from componenten where componentid = componentlink.componentid)
ELSE
Amount
END AS Amount FROM yourtable )e