How to count unique values in rows with PHPActiveRecord? - mysql

For example, I have table:
id | number
-----------
1 | 1
2 | 1
3 | 1
4 | 2
5 | 2
6 | 3
i need to count unique numbers (1, 2 and 3), that is 3
i have working SQL code:
SELECT COUNT(DISTINCT `number`) AS `total` FROM `some_table`
but i don't know how better to do this with PHPActiveRecord

There is a count() function in phpAR, but you can't make it work with DISTINCT. So, I think the easiest is:
$total = SomeModel::first(['select' => 'COUNT(DISTINCT `number`) AS `total`'])->total;

Related

MySQL display total count of values under limit

I'm pretty new to SQL and am currently trying to run a query which will return the total count of a value under a certain limit (using phpmyadmin).
Say we've got a table like so:
CarID | Car | OwnerID
-------------------
1 | Name | 1
2 | Name | 3
3 | Name | 2
4 | Name | 1
Now I would like to be able to get the total count of cars a owner has if it's under let's say 2 - to then get this:
OwnerID| TotalCars |
---------------------
2 | 1 |
3 | 1 |
How would I accomplish this? My situation is slightly different than the example I gave but it's fundamentally the same exact goal but just different numbers and more records.
When I try, those with more than the number I wish to see return with zero as their value??
(My code)
Code giving me trouble
(My result)
ID 6 has 3 properties so it shouldn't be showing me it at all and I don't understand why it's returning it as 0
You can use GROUP BY COUNT and HAVING
CREATE TABLE Table1
(`CarID` int, `Car` varchar(4), `OwnerID` int)
;
INSERT INTO Table1
(`CarID`, `Car`, `OwnerID`)
VALUES
(1, 'Name', 1),
(2, 'Name', 3),
(3, 'Name', 2),
(4, 'Name', 1)
;
SELECT `OwnerID`, COUNT(*) as countr
FROM Table1
GROUP BY `OwnerID`
HAVING countr < 2
OwnerID | countr
------: | -----:
3 | 1
2 | 1
db<>fiddle here

MySQL - Find result that have children values

I have this table structure:
product_skus table
| id |
| 1 |
...
product_sku_values table
| product_sku_id | value_id |
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
...
I need the query to find the product_sku_id, having the three values ID's (1, 2, and 3).
I'm trying with this query:
select product_sku_id from product_sku_values
where product_sku_values.value_id = 1
or product_sku_values.value_id = 2
or product_sku_values.value_id = 3
group by product_sku_id
having product_sku_id = 1
How can I do that? I'm trying lot of possibilities but no one give me the ID that I need. Can somebody help me?
Thanks.
This is a canonical method:
select psv.product_sku_id
from product_sku_values psv
where psv.value_id in (1, 2, 3)
group by psv.product_sku_id
having count(distinct psv.value_id) = 3;
If you know that product_sku_values have no duplicates, then use count(*) in the having clause.
You can simply use group by clause to get all the possible values, e.g.:
select product_sku_id, group_concat(value_id)
from product_sku_values
group by product_sku_id;
If you are only interested in value_id 1,2 and 3 then you can add one where clause, e.g:
select product_sku_id, group_concat(value_id)
from product_sku_values
where value_id in (1,2,3)
group by product_sku_id;

SQL: Count distinct row values in table

I have a similar table to this in SQL:
id |tag | entryID
---+----+--------
1 |foo | 0
2 |foo | 0
3 |bar | 3
5 |bar | 3
6 |foo | 3
7 |foo | 3
I want to run a query to count distinct rows in the table (with the id column dropped). The result should look like this (or a transpose of this table):
(tag=foo, entryID=0) | (tag=foo, entryID=3) | (tag=bar, entryID=3)
---------------------+----------------------+---------------------
2 | 2 | 2
What should this query look like?
Note: The values in each of the columns are not known beforehand.
You can do this using conditional aggregation:
select sum(tag = 'foo' and entryId = 0) as "tag=foo, entryID=0",
sum(tag = 'foo' and entryId = 3) as "tag=foo, entryID=3",
sum(tag = 'bar' and entryId = 3) as "tag=bar, entryID=0"
from t;
However, the normal method is to put the counts in rows, not columns:
select tag, entryId, count(*)
from t
group by tag, entryId;
The rows are much more versatile, because you don't have to list out every combination you might want to match.

returning rows satisfying multiple conditions for a column from a mysql table

I have mysql table with hospitals and treatments(associated with sub treatments) that they provide. I need to make mysql query on the table which returns hospitals providing all treatment/sub_treatment given in a list. For example:
From table below I need hospitals providing all treatments in list: (tretament_id, sub_treatment_id) = (1-1, 1-2). So result must be hospitals with id 1 and 8.
hospital_id | treatment_id | sub_treatment_id
-------------------------------------------------
1 | 1 | 1
1 | 1 | 2
1 | 1 | 3
_________________________________________________
4 | 1 | 1
4 | 2 | 1
_________________________________________________
8 | 1 | 1
8 | 1 | 2
_________________________________________________
7 | 2 | 1
I tried WHERE IN but it works like OR so returns hospital 4 which satisfies only (1,1). How can I write an sql query like WHERE IN but which works like AND?
Try this:
SELECT hospital_id
FROM mytable
WHERE (treatment_id, sub_treatment_id) IN ((1, 1), (1, 2))
GROUP BY hospital_id
HAVING COUNT(CASE
WHEN (treatment_id, sub_treatment_id) IN ((1, 1), (1, 2))
THEN 1
END) = 2
Demo here
You can do this using group by and having:
select hospital_id
from t
where treatment_id = 1 and sub_treatment_id in (1, 2)
group by hospital_id
having count(*) = 2;
Note: This assumes that there are no duplicates in the table. That is easy enough to fix using count(distinct), but probably not necessary.
Here is a solution using GROUP_CONCAT and JOIN:
select distinct t.hospital_id
from hospitals h and treatments t ON h.id = t.hospital_id
having GROUP_CONCAT(CONCAT(t.treatment_id, '-', t.sub_treatment_id)
ORDER BY t.treatment_id, t.sub_treatment_id)
= '1-1,1-2';

Select one fixed line and several arbitrary

I have a table with many lines. I need select several (no more than three) lines with certain values and one more. Moreover, need ORDER BY id DESC and required line position before other. Example:
id | name | group
-----------------
1 | One | null
2 | Two | null
3 | Three| 2
4 | Four | 3
5 | Five | 1
6 | Six | 2
I need lines with group == 2 (no more than three) and line with id == 2. Result:
id | name | group
-----------------
2 | Two | null
3 | Three| 2
6 | Six | 2
Line with id == 2 must be selected, other lines - no more than three. If I use WHERE id = 2 OR group = 2 LIMIT 4 than if exist more than 4 lines with group == 2, then required line with id == 2 not selected.
How solve the problem in one SQL-request?
You can try using UNION. Also note that group is a reserved word for MySQL.
SELECT aa.*
FROM (
SELECT id, firstname, lastname
FROM user
WHERE id IN (1, 2, 3, 4)
LIMIT 2
UNION ALL
SELECT id, firstname, lastname
FROM user
WHERE id = 5
) AS aa
select * from table_name where id=2
union all
select * from table_name where group=2