Please an you help me with the code by this query?.
I have two fields: 'Customer' and 'Rate'.
Rate values: (BT5A, BT5B, BT5BR, MT1, MT2, MT3)
Customers: 1000 customers by each Rate.
I would like to make a query that randomly returns 3 customers for each rate in the table, in order to have a sample of customers per rate.
How do I improve this code?
SELECT DISTINCT TOP 3
c.RUTA,c.CONTRATO,c.CODIGOANT,c.CODRUTA,c.NOMBRES,c.DIRECCION,
c.SITUACION,c.TARIFA
FROM CLIENTE AS c
INNER JOIN CUENTA AS CU ON c.CONTRATO=CU.CONTRATO
WHERE c.SITUACION NOT IN ('1','9')
AND c.tarifa='BT5A'
AND CU.MES BETWEEN '201907' AND '202007'
UNION
SELECT DISTINCT TOP 3
c.RUTA,c.CONTRATO,c.CODIGOANT,c.CODRUTA,c.NOMBRES,c.DIRECCION,
c.SITUACION,c.TARIFA
FROM CLIENTE AS c
INNER JOIN CUENTA AS CU ON c.CONTRATO=CU.CONTRATO
WHERE c.SITUACION NOT IN ('1','9')
AND c.tarifa='BT5B'
AND CU.MES BETWEEN '201907' AND '202007'
UNION
SELECT DISTINCT TOP 3
c.RUTA,c.CONTRATO,c.CODIGOANT,c.CODRUTA,c.NOMBRES,c.DIRECCION,
c.SITUACION,c.TARIFA
FROM CLIENTE AS c
INNER JOIN CUENTA AS CU ON c.CONTRATO=CU.CONTRATO
WHERE c.SITUACION NOT IN ('1','9')
AND c.tarifa='BT5BR'
AND CU.MES BETWEEN '201907' AND '202007'
I think you can use ROW_NUMBER() to solve you problem and simplify the query"
SELECT t.*
FROM (SELECT c.RUTA, c.CONTRATO, c.CODIGOANT, c.CODRUTA, c.NOMBRES, c.DIRECCION, c.SITUACION, c.TARIFA,
ROW_NUMBER() OVER (PARTITION BY c.tarifa ORDER BY NEWID()) as seqnum
FROM CLIENTE c INNER JOIN
CUENTA CU
ON c.CONTRATO = CU.CONTRATO
WHERE c.SITUACION NOT IN (1, 9) AND
CU.MES BETWEEN '201907' AND '202007'
) t
WHERE seqnum <= 3;
I doubt you really need SELECT DISTINCT. Also, I changed removed the single quotes from NOT IN. The values look like numbers, so I assume they are numbers. If the values really are strings, then use the single quotes.
EDIT:
Use exists to get avoid possible duplicates:
SELECT t.*
FROM (SELECT c.RUTA, c.CONTRATO, c.CODIGOANT, c.CODRUTA, c.NOMBRES, c.DIRECCION, c.SITUACION, c.TARIFA,
ROW_NUMBER() OVER (PARTITION BY c.tarifa ORDER BY NEWID()) as seqnum
FROM CLIENTE c
WHERE c.SITUACION NOT IN (1, 9) AND
EXISTS (SELECT 1
FROM CUENTA CU
WHERE cu.CONTRATO = c.CONTRATO AND
CU.MES BETWEEN '201907' AND '202007'
)
) t
WHERE seqnum <= 3;
Supposing this is SQL Server:
Don't join. Use IN to get the clients where the contract matches your conditions.
Use NEWID to get random numbers.
Use ROW_NUMBER to rank your rows.
If you want to use TOP, you need TOP WITH TIES and an ORDER BY clause.
The query:
SELECT TOP (3) WITH TIES
*
FROM cliente
WHERE contrato IN
(
SELECT contrato
FROM cuenta
WHERE mes BETWEEN '201907' AND '202007'
)
AND situacion NOT IN (1, 9)
ORDER BY ROW_NUMBER() OVER (PARTITION BY tarifa ORDER BY NEWID());
Related
I have 2 tables: 1st is comment, 2nd is rating
SELECT * FROM comment_table a
INNER JOIN (SELECT comment_id, SUM(rating_value) AS total_rating FROM rating_table GROUP BY comment_id) b
ON a.comment_id = b.comment_id
ORDER BY b.total_rating DESC
I tried the above SQL but doesn't work!
Object is to display a list of comments order by rating points of each comments.
SELECT s.* FROM (
SELECT * FROM comment_table a
INNER JOIN (SELECT comment_id, SUM(rating_value) AS total_rating FROM rating_table GROUP BY comment_id) b
ON a.comment_id = b.comment_id
) AS s
ORDER BY s.total_rating DESC
Nest it inside an another select. It will then output the data in the correct order.
Data Model:
Hi, I am trying to get "country with the highest number of tests".
Query:
I tried using one table.. ok... but how I get it with "countryname"? How should I make this with inner join?
Join, as you said.
select s.countryname,
s.date_,
s.total_tests
from (select
row_number() over (order by a.total_tests desc) rn,
a.date_,
a.total_tests,
c.countryname
from cases_by_countries a join country c
on c.countryid = a.country_id
) s
where s.rn = 1;
if you need only the highest you should try this
select c.CountryID, ts.Total_Tests
from Country c
inner join (
select top(1) Country_ID, Total_Tests
from CASES_BY_COUNTRIES
order by Total_Tests desc
) ts on c.CountryID = ts.Country_ID
I'm struggling to right a SQL command to get the top 10 names from the following (using standard SQL, cant use TOP) for the following 2 relations:
Orders (customer_email, item_id, date)
Items(id, name, store, price)
Any advice on how to do this? I think I would need to group them, but then what do I do to get the top 10 groupings based on count?
select *
from (select x.*, row_number() over(order by num_orders desc) as rn
from (select i.name, count(*) as num_orders
from orders o
join items i
on o.item_id = i.id
group by i.name) x) x
where rn <= 10
SELECT
COUNT(*) count_per_item
, i.id
, i.name
FROM
Orders o
JOIN
Items i
ON (o.item_id = i.id)
GROUP BY
i.id
, i.name
ORDER BY
count_per_item DESC
LIMIT 10;
I have these tables, Orders Table:
Name Null? Type
ORDER_ID NOT NULL NUMBER(5)
CUSTOMER_ID NUMBER(8)
SHIPMENT_METHOD_ID NUMBER(2)
and Shipment_method Table:
Name Null? Type
SHIPMENT_METHOD_ID NOT NULL NUMBER(2)
SHIPMENT_DESCRIPTION VARCHAR2(80)
I'm trying to get the most used shipping method based on the orders, and I'm kind of a beginner here so I need some help.
I'm thinking if it's possible to have MAX(count(order_id)) but how can I do that for each shipment_method_id?
This is another approach:
select shipment_method_id, shipment_description, count(*) as num_orders
from orders
join shipment_method
using (shipment_method_id)
group by shipment_method_id, shipment_description
having count(*) = (select max(count(order_id))
from orders
group by shipment_method_id)
You don't need MAX, you just need to return the top row
SELECT Shipment_Method_Desc
FROM (
SELECT Shipment_Method_ID, Shipment_Method_Desc, COUNT(*) AS ct
FROM Shipment_Method s
JOIN Orders o ON s.Shipment_Method_ID = o.Shipment_Method_ID
GROUP BY Shipment_Method_ID
ORDER BY ct DESC)
WHERE ROWNUM = 1
If you're using Oracle 12c or newer, you can use the row limiting clause instead of the subquery:
SELECT Shipment_Method_ID, Shipment_Method_Desc, COUNT(*) AS ct
FROM Shipment_Method s
JOIN Orders o ON s.Shipment_Method_ID = o.Shipment_Method_ID
GROUP BY Shipment_Method_ID
ORDER BY ct DESC
FETCH FIRST 1 ROW ONLY
Here is a method that allows for more than one Shipment Method having the same maximum number of Orders.
SELECT shipment_method_id
,shipment_description
,orders
FROM
(SELECT shipment_method_id
,shipment_description
,orders
,rank() OVER (ORDER BY orders DESC) orders_rank
FROM
(SELECT smm.shipment_method_id
,smm.shipment_description
,count(*) orders
FROM orders odr
INNER JOIN shipment_method smm
ON (smm.shipment_method_id = odr.shipment_method_id)
GROUP BY smm.shipment_method_id
,smm.shipment_description
)
)
WHERE orders_rank = 1
As a beginner, you may find using with useful which allows to have kind of named intermediate results:
with STATS as (select SHIPMENT_METHOD_ID, count(*) as N
from ORDERS group by SHIPMENT_METHOD_ID)
, MAXIMUM as (select max(N) as N from STATS)
select SHIPMENT_METHOD_ID, SHIPMENT_DESCRIPTION
from STATS
join MAXIMUM on STATS.N = MAXIMUM.N
natural join SHIPMENT_METHOD
I'm having an absolute brain fade
SELECT p.ProductCategory, f.ProductSubCategory, COUNT(*) AS Cnt
FROM Sales f
JOIN Products p ON f.ProductSubCategory = p.ProductSubCategory
GROUP BY p.ProductCategory, f.ProductSubCategory
ORDER BY 1,3 DESC
This shows me the count for each ProductSubCategory, I would like to see only the highest ProductSubCategory per ProductCategory.
I wish to see (I don't care about the Count value)
There are a couple of different ways to do this. One involves joining the results back to themselves and using the max aggregate. But since you are using SQL Server, you can use ROW_NUMBER to achieve the same result:
with cte as (
select p.productcategory, p.ProductSubCategory, COUNT(*) cnt,
ROW_NUMBER() over (partition by p.productcategory order by count(*) desc) rn
from products p
join sales s on p.ProductSubCategory = s.ProductSubCategory
group by p.productcategory, p.ProductSubCategory
)
select *
from cte
where rn = 1
You already got the answer, Please see the following code to. It may help you.
SELECT p.ProductCategory,
f.ProductSubCategory,
COUNT(*) AS Cnt
FROM Sales f
JOIN Products p ON f.ProductSubCategory = p.ProductSubCategory
JOIN (
SELECT p.ProductCategory,
f.ProductSubCategory,
ROW_NUMBER() OVER ( PARTITION BY p.ProductCategory,
f.ProductSubCategory
ORDER BY COUNT(*) DESC) [Row]
FROM Sales f
JOIN Products p ON f.ProductSubCategory = p.ProductSubCategory) Lu
ON P.ProductCategory = Lu.ProductCategory
AND f.ProductSubCategory = Lu.ProductSubCategory
WHERE Lu.Row = 1
GROUP By p.ProductCategory,
f.ProductSubCategory