Order_ID ship_state bill_state
121 null CA
122 WA IN
123 CA OR
124 null FL
I have a query (below) that brings back these results (above). Order_ID, Ship_state, and bill_state are each in different tables. How can I modify my query so that it will populate the null ship_state with the corresponding bill_state? Some orders are shipped directly to the billing address, this makes the shipping fields null as they are left blank. I want to generate a list of ship to states.
SELECT ca.STATE AS ship_state,
co.ID,
co.CUSTOMER_ID,
ca.ADDR_NO,
co.SHIP_TO_ADDR_NO,
c.STATE AS Bill_state,
c.NAME AS Bill_name,
ca.NAME AS Ship_name,
col.PART_ID,
col.ORDER_QTY,
ca.COUNTRY AS Ship_Country,
c.COUNTRY AS Bill_country,
co.ORDER_DATE
FROM dbo.CUST_ORDER_LINE AS col
FULL OUTER JOIN dbo.CUST_ADDRESS AS ca
FULL OUTER JOIN dbo.CUSTOMER AS c
INNER JOIN dbo.CUSTOMER_ORDER AS co
ON c.ID = co.CUSTOMER_ID
ON ca.CUSTOMER_ID = co.CUSTOMER_ID
AND ca.ADDR_NO = co.SHIP_TO_ADDR_NO
AND ca.CUSTOMER_ID = c.ID
ON col.CUST_ORDER_ID = co.ID
WHERE co.ORDER_DATE > '2014-1-1'
AND co.ID NOT LIKE 'rma%'
ORDER BY co.ID
You can use the COALESCE function:
In your SELECT:
COALESCE(ca.STATE, c.STATE) AS ship_state
This will return the value of c.STATE if ca.STATE is NULL.
Use ISNULL function,
ISNULL(ca.State, c.State) As ship_state
Related
i using this query but test case not passed
select ct.name,cm.name,sl.quantity
from sales as sl
inner join country as ct on sl.country_id=ct.id
inner join car_model as cm on cm.id=sl.model_id
where sl.sales_date BETWEEN '01-01-2020' AND '12-31-2020'
order by ct.quantity asc;
select
ct.name,
cm.name,
sl.quantity
from
sales as sl
inner join country as ct
on sl.country_id = ct.id
inner join car_model as cm
on sl.model_id = cm.id
where
sl.sales_date BETWEEN '2020-01-01' AND '2020-12-31'
order by
sl.quantity asc;
I have three tables CustomerSales & Icecream. For the purpose of understanding there is one ice cream in each sales.
CustomerSales Table contains (CustomerId, PurchaseId, postcode, IcecreamID)
Ice_Cream contains (Ice_Cream Name, Ice_Cream Id)
I'm trying to write a query which returns the amount of sales of chocolate Ice-cream to every postcode (zipcode), but I also want to know which postcodes had zero sales. Currently it's only returning the postcodes that had sales.
SELECT C.postcode, COUNT(*) AS TOTAL SALES
FROM CustomerSales C JOIN IceCream I
ON C.icecreamID = I.id AND
WHERE I.name = "Chocolate" AND C.saleyear = "2019"
GROUP BY C.postcode;
This is close to what I want but only includes the postcodes that made sales. I also want to include the postcodes that made 0 sales of chocolate icecream in 2019.
How would I do that? I've tried with rollup but think I'm doing it incorrectly.
I was also thinking
SELECT C.postcode, COUNT(*) AS TOTAL SALES
FROM CustomerSales C OUTER LEFT JOIN IceCream I
ON C.icecreamID = I.id AND
WHERE I.name = "Chocolate" AND C.saleyear = "2019"
GROUP BY C.postcode;
I think the issue is, counts return the values of rows.
Count the PurchaseId, instead of *, I think this should return the expected results:
SELECT C.postcode, COUNT(C.PurchaseId) AS TOTAL SALES
FROM CustomerSales C OUTER LEFT JOIN IceCream I
ON C.icecreamID = I.id AND
WHERE I.name = "Chocolate" AND C.saleyear = "2019"
GROUP BY C.postcode;
SELECT C.postcode, COUNT(*) AS TOTAL_SALES
FROM CustomerSales C JOIN IceCream I
ON C.icecreamID = I.id AND
WHERE I.name = "Chocolate" AND C.saleyear = "2019"
GROUP BY C.postcode
union
select c.postcode, '0' as TOTAL_SALES
FROM CUSTOMERSALES C
where c.postcode not in(select cs.postcode from
FROM CustomerSales C JOIN IceCream I
ON C.icecreamID = I.id AND
WHERE I.name = "Chocolate" AND C.saleyear = "2019"
);
Problem I see is you are doing a join and then counting number of records returned so by default records that do not have sales do not end in the join.
Join type is important here I think LEFT JOIN will show all data from first table even if no data is found in joined table, and then you will count fields from joined table, which will return NULL if none are found
Something like this:
SELECT C.postcode, COUNT(I.name) AS TOTAL SALES
FROM CustomerSales C LEFT JOIN IceCream I
ON C.icecreamID = I.id AND
WHERE I.name = "Chocolate" AND C.saleyear = "2019"
GROUP BY C.postcode;
If you want ALL the postcodes then you must do a LEFT join of the DISTINCT postcodes to CustomerSales and then to IceCream:
SELECT p.postcode, COUNT(C.PurchaseId) AS TOTAL_SALES
FROM (
SELECT DISTINCT postcode
FROM CustomerSales
) p LEFT JOIN CustomerSales C
ON C.postcode = p.postcode AND C.saleyear = '2019'
LEFT JOIN IceCream I ON C.icecreamID = I.id AND I.name = 'Chocolate'
GROUP BY p.postcode;
Just to be clear, you want to use a LEFT JOIN, move the condition on I to the ON clause and change the COUNT():
SELECT C.postcode, COUNT(i.id) AS TOTAL SALES
FROM CustomerSales C LEFT JOIN
IceCream I
ON C.icecreamID = I.id AND
I.name = 'Chocolate'
WHERE C.saleyear = 2019
GROUP BY C.postcode;
I have problem that I hope someone can help me with.
SELECT a.country_name, s.state_name, c.city_id,
LEAST (c.next_1, c.next_2, c.next_3) AS next_visit,
MAX(v.visit_time) AS last_visit
FROM city c
INNER JOIN country a ON a.id = c.country
INNER JOIN state s ON s.id = c.state
INNER JOIN visit_log v ON CONCAT(c.country, c.state, c.city_id) = CONCAT(v.country, v.state, v.city_id)
GROUP BY CONCAT(v.country, v.state, v.city_id)
ORDER BY a.id ASC, s.id ASC, c.city_id
My main problem now is that I can't get the col_1 and col_2 from the visit_log corresponding with MAX(visit_log)
SQLfiddle
You can add the "latest" requirement to the join condition:
SELECT *
FROM city c
JOIN country a
ON a.id = c.country
JOIN state s
ON s.id = c.state
JOIN visit_log v
ON v.country = c.country
AND v.state = c.state
AND v.city_id = c.city_id
AND visit_time =
(
SELECT MAX(visit_time)
FROM visit_log v2
WHERE v2.country = c.country
AND v2.state = c.state
AND v2.city_id = c.city_id
)
You can find many other approaches in the greatest-n-per-group+mysql tag. For optimal speed you'd use an approach using variables.
You can try this:-
SELECT C.NAME, S.NAME, CN.ID, NV.Next_visit_1, VL.visited
FROM COUNTRY C INNER JOIN next_visit NV ON C.ID = NV.Country
INNER JOIN STATE S ON NV.State = S.ID
JOIN CITY
INNER JOIN visitor_log VL ON CONCAT(NV.country, NV.state, NV.city) = CONCAT(VL.country, VL.state, VL.city)
When I run this query, I get duplicate lines. Specifically, the order_ID is repeated for every possible ship_state related to that Customer_ID. If I remove the cust_address table from the query, I get the correct number of lines. How can I get just the Ship_states related to that particular order. Thanks.
SELECT
co.ID AS order_ID,
col.PART_ID,
col.ORDER_QTY,
co.STATUS,
co.SHIPTO_ID,
co.CUSTOMER_PO_REF,
co.CUSTOMER_ID,
c.STATE AS Bill_State,
ca.STATE AS Ship_State
FROM
dbo.CUSTOMER_ORDER AS co
INNER JOIN
dbo.CUST_ORDER_LINE AS col ON co.ID = col.CUST_ORDER_ID
INNER JOIN
dbo.CUSTOMER AS c ON co.CUSTOMER_ID = c.ID
INNER JOIN
dbo.CUST_ADDRESS AS ca ON c.ID = ca.CUSTOMER_ID
WHERE
(co.ORDER_DATE > '2014-01-01') AND (co.ID NOT LIKE 'rma%')
ORDER BY order_ID
This gave me unique order lines and order numbers for each shipping address. The next challenge is to figure out a way to populate the rows that have the same shipping and billing address. For these orders the shipping fields are null and information from the customer table is used instead.
SELECT ca.STATE AS ship_state,
co.ID,
co.CUSTOMER_ID,
ca.ADDR_NO,
co.SHIP_TO_ADDR_NO,
c.STATE AS Bill_state,
c.NAME AS Bill_name,
ca.NAME AS Ship_name
FROM
dbo.CUST_ORDER_LINE AS col
FULL OUTER JOIN
dbo.CUSTOMER_ORDER AS co ON col.CUST_ORDER_ID = co.ID
FULL OUTER JOIN
dbo.CUST_ADDRESS AS ca
FULL OUTER JOIN
dbo.CUSTOMER AS c ON ca.CUSTOMER_ID = c.ID
ON
co.CUSTOMER_ID = c.ID
AND
co.CUSTOMER_ID = ca.CUSTOMER_ID
AND
co.SHIP_TO_ADDR_NO = ca.ADDR_NO
WHERE
(co.ORDER_DATE > '2014-1-1') AND (co.ID NOT LIKE 'rma%')
ORDER BY co.ID
Hi I want to show the county in the following query but if county does not exist, return the city instead.
SELECT P.id AS id, SUM(P.price) AS price,
P.tax,
county
FROM Purchases AS P
JOIN Status AS S ON S.id = T.status_id
JOIN Shipping AS Ship ON S.shipping_id= Ship.id
JOIN Shipping_Addresses AS SA ON Ship.shipping_address_id = SA.id
JOIN Zip_Codes AS ZIP ON ZIP.zip_code = SA.zip_code
JOIN Counties AS C ON ZIP.city = C.city
JOIN States AS STATE ON STATE.id = C.county_state_id
GROUP BY ZIP.zip_code
ORDER BY county
Thanks
Try using COALESCE():
COALESCE(county, city) AS location
If county is NULL it will return the value of city instead.
So:
SELECT P.id AS id, SUM(P.price) AS price,
P.tax,
COALESCE(county, city) AS location