My table in MySQL
http://joxi.ru/5mdWRV8tyQzyr1
My programm pass array users
$ids = [1, 3, 7];
My query for table:
SELECT responsible_id, count(id) as count
from test
WHERE active = 1
AND status = 3
AND responsible_id in (1, 3, 7)
GROUP BY responsible_id
ORDER BY count(id)
I get result http://joxi.ru/vAWYGq0IMxdjmW
But, I need also first row with responsible_id = 7 and count = 0 if not exist on table.
To do what you want, use a left join:
SELECT v.responsible_id, count(t.id) as count
FROM (SELECT 1 as responsible_id UNION ALL
SELECT 3 as responsible_id UNION ALL
SELECT 7 as responsible_id
) v LEFT JOIN
test t
ON t.responsible_id = v.responsible_id AND
t.active = 1 AND
t.status = 3
GROUP BY v.responsible_id
ORDER BY count(id);
Note that the conditions in the WHERE have been moved to the ON clause.
Related
I have this code here
INSERT INTO Directory.CatalogTaxonomy (`CatalogId`, `TaxonomyId`, `TaxonomyTypeId`, `IsApprovalRelevant`)
SELECT cat.CatalogId, dep.Id, #department_type, false
FROM Directory.Catalog cat
JOIN (SELECT * FROM (
SELECT * FROM Taxonomy.Department LIMIT 10
) as dep_tmp ORDER BY RAND() LIMIT 3) AS dep
WHERE cat.CatalogId NOT IN (SELECT CatalogId FROM Directory.CatalogTaxonomy WHERE TaxonomyTypeId = #department_type)
AND cat.UrlStatus = #url_status_green
AND (cat.StatusId = #status_published
OR cat.StatusId = #status_review_required);
And the problem is that, it should for each catalog take the first 10 elements from Department and randomly choose 3 of them, then add to CatalogDepartment 3 rows, each containing the catalog id and a taxonomy id. But instead it randomly chooses 3 Department elements and then adds those 3 elements to each catalog.
The current result looks like this:
1 000de9d7-af8b-4bac-bdbd-e6e361e5bc5e
1 001d4060-2924-4c75-b304-d780454f261b
1 001bc4b8-c1bc-498d-9aee-3825a40587d5
2 000de9d7-af8b-4bac-bdbd-e6e361e5bc5e
2 001d4060-2924-4c75-b304-d780454f261b
2 001bc4b8-c1bc-498d-9aee-3825a40587d5
3 000de9d7-af8b-4bac-bdbd-e6e361e5bc5e
3 001d4060-2924-4c75-b304-d780454f261b
3 001bc4b8-c1bc-498d-9aee-3825a40587d5
As you can see, there are only 3 departments chosen and repeated for every catalog
If you think that the query:
SELECT * FROM (
SELECT * FROM Taxonomy.Department LIMIT 10
) as dep_tmp
ORDER BY RAND() LIMIT 3
that you join to Directory.Catalog returns 3 different departments for each catalog then you are wrong.
This query is executed only once and returns 3 random departments which are joined (always the same 3) to Directory.Catalog.
What you can do is after you CROSS JOIN 10 departments to Directory.Catalog, choose randomly 3 of them for each catalog.
Try this:
INSERT INTO Directory.CatalogTaxonomy (`CatalogId`, `TaxonomyId`, `TaxonomyTypeId`, `IsApprovalRelevant`)
WITH cte AS (
SELECT cat.CatalogId, dep.Id AS TaxonomyId, #department_type AS TaxonomyTypeId, false AS IsApprovalRelevant
FROM Directory.Catalog AS cat
CROSS JOIN (SELECT * FROM Taxonomy.Department LIMIT 10) AS dep
WHERE cat.CatalogId NOT IN (SELECT CatalogId FROM Directory.CatalogTaxonomy WHERE TaxonomyTypeId = department_type)
AND cat.UrlStatus = #url_status_green
AND (cat.StatusId = #status_published OR cat.StatusId = #status_review_required);
)
SELECT t.CatalogId, t.TaxonomyId, t.TaxonomyTypeId, t.IsApprovalRelevant
FROM (
SELECT *, ROW_NUMBER() OVER (PARTITION BY CatalogId ORDER BY RAND()) rn
FROM cte
) t
WHERE t.rn <= 3
Note that this:
SELECT * FROM Taxonomy.Department LIMIT 10
does not guarantee that you get the first 10 elements from Department because a table is not ordered.
mytable contains records for id 1, 2, 3, 10, 12 and 20, and specifically does not include records for id 5 and 15.
How can I perform some query such as:
SELECT id, id IN (1,5,10,15,20) AS status
FROM mytable
WHERE id IN (1,5,10,15,20);
and return records:
id status
1 true
5 false
10 true
15 false
20 true
If there was some other table, I could just outer join mytable, but there is none. The following will certainly not work, but is there some sort of fictional table I can join against?
SELECT id, isnull(mytable.id) AS status
FROM *
LEFT OUTER JOIN mytable
WHERE id IN (1,5,10,15,20);
You can create a derived table in the FROM clause:
SELECT i.id, (t.id is not null) AS status
FROM (SELECT 1 as id UNION ALL SELECT 5 UNION ALL SELECT 10 UNION ALL SELECT 15 UNION ALL SELECT 20
) i LEFT JOIN
mytable t
ON i.id = t.id;
I want to retrieve the table value in order of from most to least. For example, if we had a single column table like the following,
selected_val
2
3
3
2
1
3
1
1
1
4
I need a SQL that will return the values in the order of 1, 3, 2, 4, because there are four 1's, three 3's, two 2's, and one 4 in the table. I want 1,1,1,1,3,3,3,2,2,4. Is this possible?
ANd if i add more colums that
selected_val Rack
2 A
3 A
3 B
2 B
1 C
3 C
1 A
1 A
1 B
4 C
Thanks for the help
you can use count and group by
select selected_val
from my_table
group by selected_val
order by count(*) DESC
for the secondo part of the question you can use group concat if you need the rack related to selected_vale
select selected_val, group_concat(rack)
from my_table
group by selected_val
order by count(*) DESC
or add the column rack to group by if you need the relative counting and order
select selected_val, rack
from my_table
group by selected_val, rack
order by count(*) DESC
TRY THIS for the desired output and you can select other columns as well:
select t.selected_val
from test t
inner join (
select t1.selected_val, count(1) ord
from test t1
group by t1.selected_val) t2 on t2.selected_val = t.selected_val
order by t2.ord desc
OUTPUT:
1
1
1
1
3
3
3
2
2
4
Output is not actually in row but you can use GROUP_CONCAT to retrieve output in a row.
Use subquery to count, then LEFT JOIN result to the subquery's result and order by count.
select t1.selected_val from table t1
left join (
SELECT
t2.selected_val,
count(*) AS count
FROM table t2
GROUP BY selected_val
) t3 on t1.selected_val = t3.selected_val
ORDER BY t3.count DESC;
Using Cross Join.
select A.C,A.Rack from
(select selected_val,Rack,count(*) c from #TableName group by selected_val,Rack)a
,(select selected_val,Rack,count(*) c from #TableName group by selected_val,Rack)b
where B.c <= A.selected_val
ORDER BY A.selected_val DESC
OutPut :
I am trying to get ratings, for a particular item in my database. Not all items have a rating for 1, 2, 3, 4 or 5; when that happens, how can I fill in the row with 0's?
So, for example when I have ratings for 1,2,3 but not for 4 and 5, how could I fill in those two rows with 0's?
select
rating,
count(rating) as rating_count,
(count(rating) / (select count(item_id) from ratings where item_id = 3) * 100) as percent,
avg(rating)
from ratings
where item_id = 3
group by rating desc
with rollup
Here is the above result for the above query, as you can see there is no 1 and 2 rating, how can I get those where rating_count, percent and avg(rating) are zeros?
#Hogan's answer:
This is what I have got working (based on #Hogan's original query):
select
r_list.r as rating,
ifnull(count(rating), 0) as rating_count,
ifnull((count(rating) / (select count(item_id) from ratings where item_id = ?) * 100), 0) as percent,
ifnull(avg(rating), 0)
from (SELECT 1 AS r
UNION ALL
SELECT 2 AS r
UNION ALL
SELECT 3 AS r
UNION ALL
SELECT 4 AS r
UNION ALL
SELECT 5 AS r
) r_list
left join ratings on r_list.r = ratings.rating and item_id = ?
group by r_list.r desc
with rollup
You will use someting along the lines of this to replace the null values as a 0:
SELECT ISNULL(rating, 0 ) FROM myTable
My database has a simple table, with two columns, BID and Value. There may be some records in the database with same BID, like this:
BID Value
Record1: BID = 1, Value = 0
Record2: BID = 1, Value = 3
Record3: BID = 2, Value = 4
Record4: BID = 2, Value = 5
Record5: BID = 2, Value = 6
Record6: BID = 3, Value = 7
Now I want to write a SQL query that can get the total count of the BID that has more than one corresponding records.
In the above sample, BID 1 has 2 corresponding records, and BID 2 has 3. So the total count of BID values that has more than one corresponding records is 2.
How to write such a SQL query?
You are looking for an aggregation query.
SELECT COUNT(*)
FROM (
SELECT BID, COUNT(*) cnt
FROM your_table
GROUP BY BID
HAVING COUNT(*) > 1
) q
The inner query here groups your bids together, counts how many in each group, and then selects only those groups with more than 1 value.
The outer query simply counts the results of that query.
You can see how it works here: http://sqlfiddle.com/#!9/0c9e6/3
declare #t table (bid int,val int)
insert into #t (bid,val)values (1,0),(1,3),(2,4),(2,5),(2,6),(3,7)
;with cte as (
select bid,
val,ROW_NUMBER()OVER(PARTITION BY bid order by val )RN from #t
)
select COUNT( DISTINCT bid) from cte
where RN > 1
you need only 2 count one for checking the count of values for each id and the other for all ids who has more than one value, you don't need to use having:
SELECT COUNT(*)
FROM (
SELECT BID, COUNT(*) CNT
FROM your_table
GROUP BY BID
) q
WHERE CNT>1