Querying a table using SQL - columns - sql

I am trying to query on a table. Let's say there 3 columns, color, car brand, and car model.
I want to exclude all blue and green colors cars, and no Honda Civic. This is the where statement I have below:
color not in ("blue", "green")
and (carBrand not = "Honda" and carModel not = "Civic").
I tried using the above statement, and it actually excludes all Honda, all Civic, and exclude any color that is blue or green. I've decided to break the query into two pieces and running them in sequence below:
color not in ("blue","green")
Then from that list run below:
carBrand not ="Honda" and carModel not = "Civic"
My question is, can I have done the above action with one query rather two queries.
FYI, I like Honda Civics, just thought it was a good example since a lot of people know that car model.
Thanks in advance.
Added new comments below for ease of reference.
I tried using the codes below. The code excludes the scenario of
Red, Honda, Accord. I have also added a sample table of the data for reference. Thanks for the help.
SELECT Color, CarBrand, CarModel
FROM ColorCarModel
WHERE (
(Color Not In ('green','blue'))
AND (CarBrand Not In 'Honda')
AND (CarModel Not In 'Civic')
);
Example data:
ID Color CarBrand CarModel
1 Green Honda Civic
2 Blue Honda Civic
3 Red Honda Civic
4 Green Ford Civic
5 Blue Ford Taurus
6 Red Ford Taurus
7 Red Honda Accord
8 Red Ford Explorer

SELECT Color, CarBrand, CarModel FROM YourTable
WHERE Color NOT IN ('green','blue')
AND CarBrand NOT IN ('Honda')
AND CarModel NOT IN ('Civic');
Try this and let me know if this helps you.

I didn't get what you wanted to exlude based on the 3 filters ... try this
where not (color in ('blue','green') and carBrand ='Honda' and carModel = 'Civic')

The problem with your original where clause is that you applied the not in operator separately to the populations of CarBrand and CarModel. You had:
(CarBrand Not In ("Honda")) and (CarModel Not In ("Civic"))
Instead, you want:
Not(CarBrand = "Honda" and CarModel = "Civic")
Here is a working example:
data ColorCarModel;
format id best. color $20. CarBrand $20. CarModel $20.;
input id color CarBrand CarModel;
datalines;
1 Green Honda Civic
2 Blue Honda Civic
3 Red Honda Civic
4 Green Ford Civic
5 Blue Ford Taurus
6 Red Ford Taurus
7 Red Honda Accord
8 Red Ford Explorer
9 Red Dummy Civic
run;
proc sql;
select color, CarBrand, CarModel
from ColorCarModel
where (
upcase(color) not in ('GREEN','BLUE') AND
NOT (upcase(CarBrand) = 'HONDA' AND upcase(CarModel) = 'CIVIC')
);
quit;
Notice also that I apply upcase() to the variables before comparing them to strings. This prevents problems caused by mixed case in the data set (i.e. where CarBrand = "Honda" would miss observations where CarBrand contains "honda").
If it's easier to think about the logic without any nesting, the following SQL provides an equivalent filter via concatenation of CarModel and CarBrand:
proc sql;
select color, CarBrand, CarModel
from ColorCarModel
where (
upcase(color) not in ('GREEN','BLUE') AND
upcase(catx('-', CarBrand, CarModel)) <> 'HONDA-CIVIC'
);
quit;
Because these filters are essentially propositional logic, a good tutorial or text on that subject could be a helpful reference. In particular, learning rules like De Morgan's law can help you think through how to transform a where clause to a different, equivalent form, which can be helpful in simplifying complex logic. If you're feeling ambitious, Discrete Mathematics by Rosen is a standard text used in CS curricula that includes an early chapter on propositional logic.

Related

Combining Rows (that contain NULL) in SQL (Amazon Redshift)

Say I have a data table like this:
Name
Color
Food
John
Black
Pizza
John
Blue
Pasta
John
Blue
Fries
I ran this code to combine ID's 2 and 3 together, so that the value for the "Food" field will show "Pasta/Fries" This is the code that I ran on Amazon Redshift:
SELECT Name, Color, listagg(Food, '/') WITHIN GROUP (ORDER BY Food) as Food FROM data GROUP BY Name, Color ORDER BY Name, Color
It successfully produced the table that I want:
Name
Color
Food
John
Black
Pizza
John
Blue
Pasta/Fries
--
Now let's say the original data table was revised and now has an additional column for Race:
Name
Color
Food
Race
John
Black
Pizza
Asian
John
Blue
Pasta
White
John
Blue
Fries
NULL
The problem I now face is when I run the code stated above, but now including Race:
SELECT Name, Color, Race, listagg(Food, '/') WITHIN GROUP (ORDER BY Food) as Food FROM data GROUP BY Name, Color, Race ORDER BY Name, Color, Race
What happens is it won't aggregate the two rows (Pasta and Fries) anymore because the value for "Race" is different for both rows. How can I modify my code so that since the value of Race for Fries is NULL, I just want to return "White" i.e. I want my final table to look like:
Name
Color
Food
Race
John
Black
Pizza
Asian
John
Blue
Pasta/Fries
White

How to set precedence to specific attribute while maintaining order

I want to select all the rows of carInventory table but have the brands which has a car in some sort of blue to be first. After, the cars in each brand sorts by year.
I was trying to alter the solution that was given in this post Take precedence on a specific value from a table
but I can't seem to keep the brands together after I figure out the rank
SELECT
*, RANK() over(
partition by colBrand
order by case when colColor like '%blue%' then 1 else 0 end
) RANK FROM inventoryTable Order By Rank, colBrand, colYear
Here's what the tables should look like. Starting Table
Brand
Make
Color
Year
Toyota
Corolla
Atlantis Blue
2015
Ford
Focus
Bayside Blue
2016
Porshe
Taycan
Grey
2019
Volkswagen
Taos
Blue
2015
Volkswagen
Jetta
White
2020
Ford
Focus
Aztec Red
2018
Search Result
Brand
Make
Color
Year
Ford
Focus
Aztec Red
2018
Ford
Focus
Bayside Blue
2016
Toyota
Corolla
Atlantis Blue
2015
Volkswagen
Taos
Blue
2020
Volkswagen
Jetta
White
2015
Porshe
Taycan
Grey
2019
Firstly, the auto industry uses the terms Make and Model to refer to what you call Brand and Make. Using your own terminology will be confusing to many.
I think if you write your order logic more precisely and completely, you will more easily find a path to a solution. And it helps to be consistent. What is "ColBrand"? ColYear? IMO you do everyone a disservice by prefacing column names with a redundant prefix. And here "col" refers to "column"? Just don't!
So it seems you want to sort by <brands with blue vehicles / brands without>, brand, year descending. Notice that Make is not included in your ordering. And notice that your Taos has year 2015 in the table but swaps that year for another in the desired output. This is one reason why you should post a script - helps to avoid typos like that and encourages others to help you.
So here is another way to accomplish that. The CTE selects all brands that have blue colors. You simply outer join the actual table to the CTE to know if the brand satisfies the blue condition. Use that knowledge in the CASE expression in the ORDER BY clause.
with blubr as (select distinct brand from #inventory where color like '%blue%')
select inv.brand, inv.make, inv.color, inv.year
from #inventory as inv left join blubr on inv.brand = blubr.brand
order by case when blubr.brand is not null then 0 else 1 end,
inv.brand, inv.year desc
;
fiddle to demonstrate Note there is a flaw in the logic of the prior answer. I've added a row to illustrate it. Do you see it? It is an easy fix to that query. Is this query better? Not really but it hopefully helps you think of different approaches to achieving the same goal.
Interesting, maybe below query can do what you need
I also made a demo fiddle
select *
from inventoryTable i
order by
case when exists ( select 1 from inventoryTable t
where t.colbrand=i.colbrand and t.colcolor like '%blue%') then 9999
else colYear end desc,colBrand asc, colyear desc

SQL Server Data in one table, but missing from another

This isn't as simple as the title. (What is an appropriate title?) I think the easiest way to describe my issue is with an example.
My goal is a list of what color balloon’s each child is missing.
Let’s assume table 1 contains the following data in 2 columns:
Child BalloonColor
Sally Yellow
Sally White
Sally Blue
Bob Red
Bob Green
Bob White
This is table 2, also 2 columns.
ColorCode Color
Y Yellow
W White
R Red
B Blue
G Green
P Pink
I need a write a result set that states what color balloon each child needs to have all colors.
Sally, R, Red
Sally, G, Green
Sally, P, Pink
Bob, Y, Yellow
Bob, B, Blue
Bob, P, Pink
My example is small, but assume I have a 1000 children in my table 1 and 75 colors in table 2. How can I check each child, one at a time, is my ultimate question? A Not in query will only yield "P, Pink", but you can see I need it at the child level, not table level.
I'm not a developer, but can write good SQL statements.
MS SQL Server 2008 R2.
Thanks in advance, Mike.
SELECT
SQ.child_name,
BC.balloon_color
FROM
(
SELECT DISTINCT
child_name
FROM
Child_Balloons
) SQ
CROSS JOIN Balloon_Colors BC
WHERE
NOT EXISTS (
SELECT *
FROM Child_Balloons CB
WHERE
CB.child_name = SQ.child_name AND
CB.balloon_color = BC.balloon_color
)

Reduce and Merge duplicate rows

I have a table with the following sampled data:
Name Color
Alice Green
Bob Black
Chris Green
Chris Black
David Red
Peter Blue
Simon Blue
Simon Red
Simon Green
Ultimately, I want to reduce the table by consolidating the Color column like:
Name Color
Alice Green
Bob Black
Chris Green, Black
David Red
Peter Blue
Simon Blue, Red, Green
such that Name can become unique.
The table has no PRIMARY KEY, I got as far as creating a new column using ROW_NUMBER to distinguishing duplicates but don't know what to do next.:
rownumber Name Color
1 Alice Green
1 Bob Black
1 Chris Green
2 Chris Black
1 David Red
1 Peter Blue
1 Simon Blue
2 Simon Red
3 Simon Green
Don't do this. Instead, normalize your tables further to e.g. a Person, Preference and a Color table (where Preference, if that is the right name for the relation, has foreign keys to Person and Color). This way, you avoid the risks of inconsistencies (you can make Person names unique if you like, but you should make Color names unique).
EDITED: if you're getting this from a join query I'll assume the data is reasonably consistent, so normalization isn't an issue. Would it be possible to change the join query to GROUP on Name instead? Much cleaner than hacking around a result set, really!
I have adopted the approach here
with a table variable to hold the temporary result set to work(hack) from.
Sorted!

SQL Query to Concat output

I have an addition SQL question, hopefully someone here can give me a hand.
I have the following mysql table:
ID Type Result
1 vinyl blue, red, green
1 leather purple, orange
2 leather yellow
and i am seeking the following output:
ID Row One Row Two
1 vinyl blue, red, green leather purple, orange
2 leather yellow
the thing is... type is not static... there are many different types and not all of them have the same ones. They need to follow in order.
Please post a show create table of your table. It's not clear what you mean in fact.
Maybe what you need is GROUP_CONCAT after all:
mysql> select ID, GROUP_CONCAT(type,' ',result) from test;
Let us know.