I have this MYSQL query
select * from {$this->table} sc
join db_sc_profile scp
on scp.subcategory_id = sc.subcategory_id
join db_profile p
on p.profile_id = scp.profile_id
where sc.subcategory_id in (" . implode(',', $subcategories) . ")
and p.profile_id in (" .implode(',', $profiles) .
group by p.profile limit ####
this query doesn't work with this line group by p.profile limit ####. So
i want to group by p.profile but limit for 12/count(profiles).
Can i do that ? please any help.
NB : I'm using Codeigniter 2
Input example
[subcategories] = Array
(
[0] => 101
[1] => 102
[2] => 103
)
[profiles] => Array
(
[0] => 5
[1] => 6
)
they are two tables in database linked by a third table
profile = [profile_id, profile_name]
subcategory = [sc_id, sc_name,...]
profile_subcategory = [profile_id, sc_id]
Related
I have a problem and there are already some similar questions but they didn't solve my problem.
I have several hotels and pictures in it. The pictures are ordered by a number. I want all hotels and the picture with the lowest number.
When I try following query I get the right order:
SELECT s25.entry_id AS id,
s25.value AS title,
s35.file AS picture,
s86.value AS picture_sort
FROM sym_entries_data_25 AS s25
LEFT JOIN sym_entries_data_34 AS s34 ON (s25.entry_id = s34.relation_id)
LEFT JOIN sym_entries_data_35 AS s35 ON (s34.entry_id = s35.entry_id)
LEFT JOIN sym_entries_data_86 AS s86 ON (s34.entry_id = s86.entry_id)
ORDER BY s86.value
I will get the Array
[0] => Array
(
[id] => 243
[title] => Hotel
[picture] => louis2.jpg
[picture_sort] => 1
)
[1] => Array
(
[id] => 243
[title] => Hotel
[picture] => louis1.jpg
[picture_sort] => 2
)
[2] => Array
(
[id] => 243
[title] => Hotel
[picture] => louis3.jpg
[picture_sort] => 3
)
...And so on
But I only want one result per hotel, so I tried a GROUP BY:
SELECT s25.entry_id AS id,
s25.value AS title,
s35.file AS picture,
s86.value AS picture_sort
FROM sym_entries_data_25 AS s25
LEFT JOIN sym_entries_data_34 AS s34 ON (s25.entry_id = s34.relation_id)
LEFT JOIN sym_entries_data_35 AS s35 ON (s34.entry_id = s35.entry_id)
LEFT JOIN sym_entries_data_86 AS s86 ON (s34.entry_id = s86.entry_id)
GROUP BY s25.value
ORDER BY s86.value
Then I only get one Result but a random one, not the first one:
[0] => Array
(
[id] => 243
[title] => Hotel
[picture] => louis3.jpg
[picture_sort] => 3
)
What could be the problem here?
when you are doing group by, you have no guarantee regarding the values of the columns you are not grouping by.
for example if you have a table with columns a and b, and data like:
a | b
-----
1 | 2
1 | 3
if you'll do select * from table group by a, you can get either 2 or 3 as the value of b.
if you only want the top result for the hotel, what you need to do is not group by, but take the result where picture_sort equals to the min(picture_sort)
Have table like this
IdRows | UpperLevelIdRows | CategoriesName |
-------------------------------------------------
2 | 0 | Transport
4 | 2 | Cars
12 | 4 | Alfa Romeo
Query
SELECT IdRows AS IdRows1, CategoriesName AS CategoriesName1 FROM categories
WHERE UpperLevelIdRows = ?
UNION
SELECT IdRows AS IdRows2, CategoriesName AS CategoriesName2 FROM categories
WHERE UpperLevelIdRows = ?
Data for placeholders is
Array
(
[0] => 2
[1] => 4
)
So
SELECT IdRows AS IdRows1 .... WHERE UpperLevelIdRows = 2
and
SELECT IdRows AS IdRows2 .... WHERE UpperLevelIdRows = 4
As result expect get array like
[0] => Array
(
[IdRows1] => 4
[CategoriesName1] => Cars
)
[1] => Array
(
[IdRows2] => 12
[CategoriesName2] => Alfa Romeo
)
But get array like this
[0] => Array
(
[IdRows1] => 4
[CategoriesName1] => Cars
)
[1] => Array
(
[IdRows1] => 12
[CategoriesName1] => Alfa Romeo
)
Instead of IdRows2 see IdRows1
If i execute only the second SELECT IdRows AS IdRows2 ..., then see as expected [CategoriesName2] => Alfa Romeo
Where is my mistake? What need to correct?
From the data i want to create select/option boxes. Like
First select box
echo '<select name="upper_level_id0" id="upper_level_id0" >
<option value="'.$IdRows1.'">'.$CategoriesName1.'</option>
</select>';
Second select box
echo '<select name="upper_level_id1" id="upper_level_id1" >
<option value="'.$IdRows2.'">'.$CategoriesName2.'</option>
</select>';
At the moment found solution using transaction. Loop through all SELECT ...
$db->beginTransaction();
foreach ( $sql_get_id_name as $k_sql => $val_sql ) {
$stmt_get_id_name = $db->prepare( $val_sql );
$stmt_get_id_name->execute( array( $data_get_id_name[$k_sql] ) );
$id_name[] = $stmt_get_id_name->fetchAll(PDO::FETCH_ASSOC);
}
$roll_back = $db->rollBack();
Use this select
select cp.IdRows p_id, cp.UpperLevelIdRows p_parent_id, cp.CategoriesName p_name,
cc.IdRows p_id, cc.UpperLevelIdRows c_parent_id, cc.CategoriesName c_name
from categories cc left join categories cp on cp.IdRows = cc.UpperLevelIdRows
where cc.UpperLevelIdRows = 4
This way you will get all the sons of a parent. The first 3 columns from the result are the parent (in your row data it will be the Cars) and the second its childs (in your row data the Alfa Romeo)
I have 2 Tables and can't get my MySQL Query to work:
First Table users:
user_id name
------------
1 Bob
2 Alice
Second Table fields:
id unser_id field_id value
-----------------------------
1 1 4 foo
2 1 5 10
3 2 4 bar
Now I would like to join the Tables in a way that outputs:
[0] => (
[user_id] => 1
[name] => Bob
[fields] => (
[4] => foo
[5] => 10
)
[1] => (
[user_id] => 2
[name] => Alice
[fields] => (
[4] => bar
)
)
Thanks a lot!
I tried:
SELECT u.user_id,
u.name
FROM users as u
INNER JOIN fields as f on u.user_id = d.user_id
But I get for every user just the first fields entry.
SELECT user_id,name,GROUP_CONCAT(value SEPARATOR ',')as field FROM users u JOIN fields f
ON u.user_id=f.unser_id GROUP BY user_id
Maybe something like this?
select u.user_id,u.name,f.field_id,f.value from users u LEFT JOIN fields f ON u.user_id = f.unser_id
First things first, I know this is incorrect currently. I know this because it doesn't work. So with that said, any assistance in getting me closer to my desired result is appreciated.
I have a query:
$query = "SELECT cat.*,
prod.title AS product,
cat1.title AS category,
(SELECT cat2.*
FROM ic_store_catalog AS cat2
WHERE cat2.parentid = cat.parentid) AS children
FROM ic_store_catalog AS cat
LEFT JOIN ic_products AS prod
ON cat.productid = prod.productid
LEFT JOIN ic_product_categories AS cat1
ON cat.categoryid = cat1.categoryid
WHERE `storeid` = $storeid
AND `column` = $column
AND `parentid` = 0
ORDER BY `the_order` ASC";
This errors out giving me: Operand should contain 1 column(s) as the problem. This exists in the sub-select guaranteed.
Now what I need to achieve when I use print_r in PHP is an Array similar in structure to this:
[0] => Array
(
[catalogID] => 165
[storeID] => 0
[categoryID] => 7
[parentID] => 0
[productID] => 4
[title] =>
[column] => 1
[the_order] => 1
[cat_order] => 1
[category] => Cookies & Brownies
[children] => Array
(
[0] => Array (
[catalogID] => 166
[storeID] => 0
[categoryID] => 8
[parentID] => 7
[productID] => 5
[the_order] => 1
[cat_order] => 1
[category] => Brownies
)
)
)
Any help in getting me closer to this result is appreciated.
(SELECT cat2.*
FROM ic_store_catalog AS cat2
WHERE cat2.parentid = cat.parentid)
You should replace cat2.* by only one column that will represent children.
I'm trying to create a messages list, like Facebook.
Showing only last the message from a users conversation (history)
when I send show mine , when I get answer show answered messages (1 row)
database data :
SQL query
SELECT m.message_id, u.username, m.subject, m.message
, m.status, UNIX_TIMESTAMP(m.date) as date
FROM users u
LEFT JOIN messages m ON m.sender_id = u.id
WHERE m.message_id in (SELECT max(msg.message_id)
FROM messages msg
WHERE msg.receiver_id = 3
GROUP BY sender_id)
UNION
SELECT m.message_id, u.username, m.subject, m.message
, m.status, UNIX_TIMESTAMP(m.date) as date
FROM users u
LEFT JOIN messages m ON m.receiver_id = u.id
WHERE m.message_id in (SELECT max(msg.message_id)
FROM messages msg
WHERE msg.sender_id = 3
GROUP BY receiver_id)
GROUP BY u.username
ORDER BY date DESC
I try to receive all messages which I send (my id = 3) and all those sent to me and group by username
SQL result:
Array
(
[0] => Array
(
[message_id] => 10
[username] => 8888
[subject] => без темы
[message] => 555
[status] => 0
[date] => 11 August 2012, 2:22
[user_image] => http://127.0.0.1/auth_system_1/upload_images/65_empty.jpg
)
[1] => Array
(
[message_id] => 7
[username] => 8888
[subject] => hi
[message] => 333
[status] => 0
[date] => 11 August 2012, 2:15
[user_image] => http://127.0.0.1/auth_system_1/upload_images/65_empty.jpg
)
[2] => Array
(
[message_id] => 4
[username] => 6666
[subject] => Тема
[message] => 2
[status] => 0
[date] => 11 August 2012, 2:02
[user_image] => http://127.0.0.1/auth_system_1/upload_images/65_empty.jpg
)
[3] => Array
(
[message_id] => 1
[username] => fffffffff
[subject] => privet
[message] => tttt
[status] => 0
[date] => 11 August 2012, 1:38
[user_image] => http://127.0.0.1/auth_system_1/upload_images/65_empty.jpg
)
)
As you can see GROUP BY username do not work. It shows 3->7 and 7->3 but 7->3 was an answer and last message. I do not know why group does not work. Maybe you can help me with more easier way to solve this problem?
So, the SQL must have "sender_id = 3" , "receiver_id = 3" and from my table data result must be
message_id -> 1
message_id -> 4
message_id -> 10
I think your query is producing the “right” results, as if you'd like to see the last message in some of the conversations, you should really group by the conversation_id. I don't see this field you in schema though.
If you do WHERE sender_id = 3 GROUP BY receiver_id, then it is correct, that query returns you messages 1 and 7, 'cos those messages had been sent to different people, thus in your design they're different conversations.
If you want to see only the very last message sent by you in general, just remove GROUP BY in the second part of your UNION. Otherwise, consider re-designing your schema.
EDIT:
Try this query:
SELECT m.message_id, u.username, m.subject, m.message,
m.status, UNIX_TIMESTAMP(m.date) as `date`
FROM users u
LEFT JOIN messages m ON m.sender_id = u.id
WHERE m.message_id IN (
SELECT max(message_id)
FROM messages
WHERE receiver_id = 3 OR sender_id = 3
GROUP BY least(sender_id,receiver_id),
greatest(sender_id,receiver_id)
);
Some notes:
UNION is not needed anymore;
This approach will treat all e-mails between 2 parties as a single conversation, which is not always true. You might want to re-design this approach;
It is a bad style to use reserved words (like date) for columns' names or aliases, try to avoid this. Or use backticks if you do use them.