SQLite GROUP BY lowest price missing results - sql

I've got a SQLite DB that houses basically a list of products and prices.
CREATE TABLE brand_list (
id INTEGER NOT NULL,
brand_name TEXT NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE product_list (
id INTEGER NOT NULL,
prod_generic VARCHAR NOT NULL,
prod_pretty VARCHAR NOT NULL,
PRIMARY KEY (id),
UNIQUE (prod_generic)
);
CREATE TABLE qty_list (
id INTEGER NOT NULL,
qty_initial VARCHAR NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE vendor_list (
id INTEGER NOT NULL,
vendor_name TEXT NOT NULL,
vendor_url VARCHAR NOT NULL, url_pretty varchar not null default 1, datacollect varchar not null default 'Y',
PRIMARY KEY (id)
);
CREATE TABLE listing (
id INTEGER NOT NULL,
brand_id INTEGER,
qty_id INTEGER,
vendor_id INTEGER,
prod_id INTEGER,
qty_actual INTEGER,
price INTEGER,
unit_price FLOAT,
timestamp VARCHAR(255),
sale INTEGER DEFAULT 0 NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY(brand_id) REFERENCES brand_list (id),
FOREIGN KEY(prod_id) REFERENCES product_list (id),
FOREIGN KEY(qty_id) REFERENCES qty_list (id),
FOREIGN KEY(vendor_id) REFERENCES vendor_list (id)
I pull a query looking at the listing table with the goal of grabbing the lowest price and listing all of the relevant information for end users (ie brands, products, qty, price, when it was pulled, where it was pulled from).
select qty_initial, qty_actual, price, MIN(unit_price), brand_name, prod_pretty, sale, timestamp, vendor_name from listing left join brand_list on listing.brand_id = brand_list.id left join product_list on listing.prod_id = product_list.id left join vendor_list on listing.vendor_id = vendor_list.id left join qty_list on listing.qty_id = qty_list.id group by prod_pretty order by brand_name, prod_pretty
What I'm seeing is that most of the data is showing up but not all of the data is showing up. And it doesn't seem consistent - but one brand might show seven out of eight entries, another brand might have everything.
The interesting part is that if I add a WHERE clause just prior to the group by and specify a brand that I know is missing entries in the original output, I'll get all of the expected output for that brand.
This isn't my world - I'm just hacking something together for my own fun. I'm certain I'm missing something fundamental here and it's likely around the GROUP BY. Any direction would be great - even a way to rethink how I'm doing this to get to where I want to be in a simpler manner.

Your query is malformed -- although SQLite does accept it. The GROUP BY columns are inconsistent with the SELECT list.
Instead, use window functions:
select qty_initial, qty_actual, price, unit_price, brand_name, prod_pretty, sale, timestamp, vendor_name
from (select qty_initial, qty_actual, price, unit_price, brand_name, prod_pretty, sale, timestamp, vendor_name,
row_number() over (partition by prod_pretty order by unit_price) as seqnum
from listing left join
brand_list
on listing.brand_id = brand_list.id left join
product_list
on listing.prod_id = product_list.id left join
vendor_list
on listing.vendor_id = vendor_list.id left join
qty_list
on listing.qty_id = qty_list.id
group by prod_pretty
) p
where seqnum = 1
order by brand_name, prod_pretty

Related

Show the names of customers that have accounts SQL Query Oracle 10G

create table customer
(cust_id integer not null,
cust_name char(20) not null ,
cust_address varchar2(200) ,
emp_id integer not null,
constraint pk_customer primary key(cust_id)
);
create table account
(account_number integer not null,
account_balance number(8,2) not null,
constraint pk_acount primary key(account_number)
);
create table has
(cust_id integer not null,
account_number integer not null,
constraint pk_has
primary key(cust_id, account_number) )
alter table has
add constraint fk_account_has foreign key(account_number)
references account(account_number);
alter table has
add constraint fk_customer_has foreign key(cust_id)
references customer(cust_id);
Q1 Show the names of customers that have accounts
Q2 Show the customer names with the names of the employees they deal with**
Q1 is a simple lookup of the cust_id in junction table has:
select c.cust_name
from customer c
where exists (select 1 from has h where h.cust_id = c.cust_id)
This phrases as: select the customers that have at least one entry in the has table.
When it comes to Q2: your data structures show no sign of employees (all we have is customers and accounts), so this cannot be answered based on the information that you provided. You might want to ask a new question for this, providing sample data for the involved tables, along with desired results and you current attempt at solving the problem.

Returning values using a query that have been awarded a bonus

I'm trying to transactionId that were randomly chosen to be awarded a bonus which is essentially just having their rewardValue be double.
Following is my schema:
CREATE TABLE rewards (
rewardId INTEGER PRIMARY KEY,
rewardType VARCHAR(20),
rewardValue NUMERIC(6,2)
);
CREATE TABLE deposit (
depositId INTEGER PRIMARY KEY,
depositDate DATE,
customerId INTEGER NOT NULL REFERENCES Customers
);
CREATE TABLE transactions (
transactionId SERIAL PRIMARY KEY,
depositId INTEGER NOT NULL UNIQUE REFERENCES Orders,
transactionAmount NUMERIC(18,2)
);
Here's my query:
select distinct t.transactionId
from transactions t join deposit d on t.depositId = d.depositId join
rewards r on 2 * r.rewardValue <= t.transactionAmount;
I get some output which is just a few values repeating over and over. Does anyone know how to fix this?
before answer your question, seems like your join have a issue.
if you want to find transactions eligible for rewards
try this ->
select distinct transactionId from
(select t.transactionId,r.rewardValue,t.transactionAmount
from transactions t join deposit d on t.depositId = d.depositId,rewards r ) tbl where 2*rewardValue <= transactionAmount

PostgreSQL SELECT JOIN

I have a problem with making a proper SELECT for my exercise:
There are two tables that I have created:
1. Customer
2. Order
ad. 1
CREATE TABLE public."Customer"
(
id integer NOT NULL DEFAULT nextval('"Customer_id_seq"'::regclass),
name text NOT NULL,
surname text NOT NULL,
address text NOT NULL,
email text NOT NULL,
password text NOT NULL,
CONSTRAINT "Customer_pkey" PRIMARY KEY (id),
CONSTRAINT "Customer_email_key" UNIQUE (email)
)
ad.2
CREATE TABLE public."Order"
(
id integer NOT NULL DEFAULT nextval('"Order_id_seq"'::regclass),
customer_id integer NOT NULL,
item_list text,
order_date date,
execution_date date,
done boolean DEFAULT false,
confirm boolean DEFAULT false,
paid boolean DEFAULT false,
CONSTRAINT "Order_pkey" PRIMARY KEY (id),
CONSTRAINT "Order_customer_id_fkey" FOREIGN KEY (customer_id)
REFERENCES public."Customer" (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
Please do not mind how columns properties were set.
The problem I have is following:
How to make a SELECT query which will give me as a result ids and emails of customers who have ordered something after '2017-09-15'
I suppose that this should go with JOIN but none of the queries I tried have worked :/.
Thanks!
You should post the queries that you tried, but in the meantime try this. It's a simple join :
SELECT DISTINCT id
, email
FROM public."Customer" c
JOIN public."Order" o
ON c.id = o.customer_id
WHERE order_date > '2017-09-15'
In table "Order" you just need to add current constraint for customer id:
customer_id integer REFERENCES Customer (id)
for more information check this page:
https://www.postgresql.org/docs/9.2/static/ddl-constraints.html
So, the query should be like this:
SELECT id, email
FROM Customer
INNER JOIN Order
ON (Order.customer_id = Customer.id)
WHERE order_date >= '2017-09-15'
Also, the useful docs you can check: https://www.postgresql.org/docs/current/static/tutorial-join.html

Count Query Reciepe/Ingredients

basically I've been working on an SQL question which is asking to display each ingredient along with the total number of recipes it's included in. It also must only include the ingredients that occur more than 10 times and descending order of ingredient popularity and ascending order of ingrdesc.
the tables are as followed:
CREATE TABLE Ingredient
(
idI NUMBER constraint pk_Ingredient PRIMARY KEY ,
ingrDesc VARCHAR2(100) constraint nn1Ingredient not null
);
CREATE TABLE Recipe
(
idR NUMBER constraint pk_recipe PRIMARY KEY ,
recipeTitle VARCHAR2(200) constraint nn1Recipe not null,
prepText VARCHAR2(4000),
cuisineType VARCHAR2(50),
mealType VARCHAR2(30) DEFAULT NULL,
CONSTRAINT ch_mealType CHECK (mealType IN ('starter', 'main', 'dessert', null))
);
CREATE TABLE RecpIngr
(
idR NUMBER ,
hidI NUMBER ,
CONSTRAINT pk_RecpIngr PRIMARY KEY (idR, idI),
CONSTRAINT fk1RecpIngr_recipe foreign key(idR) references Recipe,
CONSTRAINT fk2RecpIngr_ingredient foreign key(idI) references Ingredient
)
organization index;
So far I have this query:
SELECT ingrDesc,
COUNT (idR) As num_of_recipes
FROM RespIngr
WHERE num_of_recipes <10
ORDER BY num_of_recipes DES, ingrDes ASC;
Try this:
SELECT ingrDesc,
COUNT (idR) As num_of_recipes
FROM RespIngr
GROUP BY ingrDesc
HAVING COUNT (idR) > 10
ORDER BY num_of_recipes DESC, ingrDesc ASC;
I don't get it. You show a query from table RespIngr but you don't mention such a table. You show a table RecpIngr but that doesn't contain the field ingrDesc.
To get the fields you show, the query must contain a join of the table that contains the recipes and ingredients and the table that contains the description of the ingredients.
with
RCount( IngID, RecipeCount )as(
select hidI, count(*)
from RecpIngr
group by hidI
having count(*) > 10
)
select i.ingrDesc as "Ingredient", rc.RecipeCount as "Number of Recipes"
from Ingredient i
join RCount rc
on rc.IngID = i.idI;

Join multiple tables, including one table twice, and sort by counting a group

I am an amateur just trying to finish his last question of his assignment (it is past due at this point, just looking for understanding) I sat and shot attempts at this for almost 5 hours now across two days, and have had no success.
I have tried looking through all the different types of joins, couldn't get grouping to work (ever) and have had little luck with the sorting as well. I can do all of these things one at a time, but the difficulty here was getting all of these things to work in union.
This is the question:
Write a SQL query to retrieve a list that has (source city, source code, destination city,
destination code, and number-of-flights) for all source-dest pairs with at least 2 flights. Order
by the number_of_flights. Note that the “dest”, and “source” attributes in the “flights” table
are both referenced to the “airportid” in the “airports” table.
Here are the tables I have to work with (also came with about 3000 lines of dummy entries)
create table airports (
airportid char(3) primary key,
city varchar(20)
);
create table airlines (
airlineid char(2) primary key,
name varchar(20),
hub char(3) references airports(airportid)
);
create table customers (
customerid char(10) primary key,
name varchar(25),
birthdate date,
frequentflieron char(2) references airlines(airlineid)
);
create table flights (
flightid char(6) primary key,
source char(3) references airports(airportid),
dest char(3) references airports(airportid),
airlineid char(2) references airlines(airlineid),
local_departing_time date,
local_arrival_time date
);
create table flown (
flightid char(6) references flights(flightid),
customerid char(10) references customers,
flightdate date
);
The first problem I ran in to was outputting airports.city twice in the same query but with different results. Not only that, but no matter what I tried when grouping I would always get the same result:
Not a GROUP BY expression
Normally I have fun trying to piece these together, but this has been frustrating. Help!
select source.airportid as source_airportid,
source.city source_city,
dest.airportid as dest_airportid,
dest.city as dest_city,
count(*) as flights
from flights
inner join airports source on source.airportid = flights.source
inner join airports dest on dest.airportid = flights.dest
group by
source.airportid,
source.city,
dest.airportid,
dest.city
having count(*) >= 2
order by 5;
Have you tried a subquery?
SELECT source_airports.city,
source_airports.airportid,
dest_airports.city,
dest_airports.airportid,
x.number_of_flights
FROM
(
SELECT source, dest, COUNT(*) as number_of_flights
FROM flights
GROUP BY source, dest
HAVING COUNT(*) > 1
) as x
INNER JOIN airports as dest_airports
ON dest_airports.airportid = x.dest
INNER JOIN airports as source_airports
ON source_airports.airportid = x.source
ORDER BY x.number_of_flights ASC