Good Day! All Fridays,
I have some problem in my sql query. I'm using IN class with subquery like this
SELECT
cm.category_id,
cd.name
FROM
category_master cm,
category_detail cd,
brand_to_categories b2c
WHERE
cm.category_id = b2c.category_id
AND
cd.category_id = cm.category_id
AND
cd.language_id = 1
AND
cm.status <> 2
AND
cm.category_id IN (SELECT DISTINCT sub_dd.categories FROM distribution_master bdm, distribution_detail bdd, subscription_category_to_brand_user sub_dd WHERE bdd.distribution_id = bdm.distribution_id AND bdm.distributor_id = 35 AND bdd.brand_id = 7191 AND sub_dd.sub_d_id = bdd.id)
AND
b2c.brand_id = 7191;
The following is the sub-query which is creating problem for me.
cm.category_id IN (
SELECT DISTINCT
sub_dd.categories
FROM
distribution_master bdm,
distribution_detail bdd,
subscription_category_to_brand_user sub_dd
WHERE
bdd.distribution_id = bdm.distribution_id
AND
bdm.distributor_id = 35
AND
bdd.brand_id = 7191
AND
sub_dd.sub_d_id = bdd.id)
the result of the sub-query is like this.
3913,4517,6059,7137,7138,7139,7140,7141,7144
this result is coming from only single row in the target table because I stored these ids as string in the filed.
Now the problem is this, I can not get results of the all categories. Main query final result only return one category information which category_id is 3913. But if I run this query manually with sub-query values instead of the sub-query then it returns all the categories results.
Manual query with sub-query values is like this
SELECT
cm.category_id,
cd.name
FROM
category_master cm,
category_detail cd,
brand_to_categories b2c
WHERE
cm.category_id = b2c.category_id
AND
cd.category_id = cm.category_id
AND
cd.language_id = 1
AND
cm.status <> 2
AND
cm.category_id IN (3913,4517,6059,7137,7138,7139,7140,7141,7144)
AND
b2c.brand_id = 7191;
Please help me regarding this problem.
Sorry I forget, I'm using Mysql
Assuming you are using MySQL, use FIND_IN_SET:
WHERE
...
FIND_IN_SET(cm.category_id,
(SELECT DISTINCT sub_dd.categories
FROM distribution_master bdm,
distribution_detail bdd,
subscription_category_to_brand_user sub_dd
WHERE bdd.distribution_id = bdm.distribution_id AND
bdm.distributor_id = 35 AND
bdd.brand_id = 7191 AND
sub_dd.sub_d_id = bdd.id)) > 0
If you are using SQL Server, then we have to do a bit more work:
WHERE ',' + (SELECT DISTINCT ...) + ',' LIKE '%,' + cm.category_id + ',%'
General comment: Avoid storing CSV data in your SQL tables. MySQL almost made the problem worse by offering FIND_IN_SET and making it easier to skirt good table design.
Related
I need to adjust this query to do the search (like) in another column and another table.
See:
$query2 = "
select distinct(lances.codigo)
, datacompra
, horacompra
, cupom
from lances
, ".$tabelaCad."
where lances.idcliente = ".$tabelaCad.".id
and lances.datapgto = '0000-00-00'
and lances.horapgto = '00:00:00'
and (".$tabelaCad.".nome like '%".$cliente."%' or ".$tabelaCad.".usuario like '%".$cliente."%')
group
by lances.codigo
order
by lances.datacompra desc
, lances.horacompra desc
";
He currently searches only on: ".$tabelaCad.".nome and ".$tabelaCad.".usuario.
The variable $tabelaCad is the name of a table called cadastro, and the variable cliente is the one that receives the search POST.
I need her to look too in the column codigo from the table lances and in a new table called registro in the columns reg1 e reg2.
What would the query look like in this case? I have tried several ways and it does not work.
I am working with MySQL 5.7, still...
After a long discussion we found the last relation between the tables.
It is registro.reg1 to lances.codigo.
So the best way to solve the problem is to work with the inncer join.
You save unnecessary typing and can address the tables with aliases which is much more comfortable for writing procedures.
Here is my finished solution:
<?php
$query2 = "
select
distinct lc.codigo as codigo,
lc.datacompra as datacompra,
lc.horacompra as horacompra,
lc.cupom as cupom
from `lances` as lc
inner join `".$tabelaCad."` as ca on lc.idcliente = ca.id
inner join `registr` as ri on lc.codigo = ri.reg1
where lc.idcliente = ca.id
and lc.datapgto = '0000-00-00'
and lc.horapgto = '00:00:00'
and (ca.nome like '%".$cliente."%' or ca.usuario like '%".$cliente."%')
group
by lc.codigo
order
by lc.datacompra desc, lc.horacompra desc
";
?>
I put them in the selection because I do not know exactly what you intend to xD
This query was supposed to return me four rows: which are four people with status 50 (which, in the application means "maternity leave"). But it returns only one.
On HeidiSQL the query doesn't even run because it displays a
syntax error on line 13:
(...)
corresponds to your MariaDB server version for the right syntax to use near 'a.id_regiao = '$id_regiao'
AND a.cod_status = 50
AND a.status' at line 13 */"
Here is the query. I'm slowly becoming familiar with sql statements and i did search a lot on SO before asking it:
//SELECTING PROJECT DATA
$query = "SELECT b.id_clt,b.nome AS nome_clt,
a.id_evento AS a_id_evento,a.data AS a_data,a.data_retorno AS a_data_retorno,
c.id_evento AS c_id_evento,c.data AS c_data,c.data_retorno AS c_data_retorno,
(SELECT nome FROM projeto WHERE id_projeto = a.id_projeto) AS nome_projeto,
(SELECT nome FROM curso WHERE id_curso = b.id_curso) AS nome_curso,
DATE_FORMAT(a.data,'%d/%m/%Y') AS a_data_br,
DATE_FORMAT(a.data_retorno,'%d/%m/%Y') AS a_data_retorno_br,
DATE_FORMAT(c.data,'%d/%m/%Y') AS c_data_br,
DATE_FORMAT(c.data_retorno,'%d/%m/%Y') AS c_data_retorno_br
FROM rh_eventos AS a
INNER JOIN rh_clt AS b ON (a.id_clt = b.id_clt AND a.cod_status = 50)
LEFT JOIN rh_eventos AS c ON (b.id_clt = c.id_clt AND c.cod_status = 54)
WHERE $cond_projeto a.id_regiao = '$id_regiao'
AND a.cod_status = 50
AND a.status = 1
AND NOW() BETWEEN a.data AND a.data_retorno
ORDER BY nome_projeto,b.nome;";
The problem is here in the query:
WHERE $cond_projeto a.id_regiao = '$id_regiao'
This inserts a variable (or maybe a full test?) without proper syntax. If it is a variable, include the table's column name in the criterium. If it is a full test, include AND like so:
WHERE $cond_projeto AND a.id_regiao = '$id_regiao'
Beware though! Use prepared statements, your code now appears to be vulnerable to SQL injection attacks (and those are not to be trifled with).
Here is the query, (as seen by using an echo before it) . I can see the output on heidsql now. Now its better for us to check it:
SELECT b.id_clt,b.nome AS nome_clt,
a.id_evento AS a_id_evento,a.data AS a_data,a.data_retorno AS a_data_retorno,
c.id_evento AS c_id_evento,c.data AS c_data,c.data_retorno AS c_data_retorno,
(SELECT nome FROM projeto WHERE id_projeto = a.id_projeto) AS nome_projeto,
(SELECT nome FROM curso WHERE id_curso = b.id_curso) AS nome_curso,
DATE_FORMAT(a.data,'%d/%m/%Y') AS a_data_br,
DATE_FORMAT(a.data_retorno,'%d/%m/%Y') AS a_data_retorno_br,
DATE_FORMAT(c.data,'%d/%m/%Y') AS c_data_br,
DATE_FORMAT(c.data_retorno,'%d/%m/%Y') AS c_data_retorno_br
FROM rh_eventos AS a
INNER JOIN rh_clt AS b ON (a.id_clt = b.id_clt AND a.cod_status = 50)
LEFT JOIN rh_eventos AS c ON (b.id_clt = c.id_clt AND c.cod_status = 54)
WHERE a.id_regiao = '1' AND a.cod_status = 50
AND a.status = 1
AND NOW() BETWEEN a.data AND a.data_retorno ORDER BY nome_projeto,b.nome;
I can now see the output on heidsql, though i still cant figure out why it doesent bring the other thre rows.
I have an SQL query that fetches posts from a database. Everything works fine, but now I need to order the results by the number of comments each post has. The comments are on a separate table and they have a post_id column that links it to the post. I need to order the posts by the count of the comments table based on a shard ID? I have tried everything but every time I try to add something to my query it stops running completely and leaves my page blank. I need help to know where to put the other JOIN statement. This is my query:
$union = "UNION ALL
(
SELECT DISTINCT wallposts.p_id,wallposts.is_profile_notes,wallposts.times_viewed,wallposts.columnTimesShared,
wallposts.marked,wallposts.secure_id,wallposts.reshared,wallposts.group_id,
wallposts.totaluploads,wallposts.WallUploadID,wallposts.type,
wallposts.value,wallposts.media,wallposts.youtube,wallposts.post_type,
wallposts.privacy,wallposts.tagedpersons,wallposts.with_friends_tagged,wallposts.emotion_head,wallposts.selected_emotion,wallposts.title,
wallposts.url,wallposts.description,wallposts.cur_image,
wallposts.uip,wallposts.likes,wallposts.userid,
wallposts.posted_by,wallposts.post as postdata,wallusers.*,
UNIX_TIMESTAMP() - wallposts.date_created AS TimeSpent,
PosterTable.mem_pic as posterPic, PosterTable.gender as posterGender,PosterTable.oauth_uid as poster_oauth_uid, PosterTable.username as posterUsername,
PosterTable.mem_fname as posterFname,PosterTable.work as posterWork,
PosterTable.mem_lname as posterLname,walllikes_track.id as PostLikeFound,wallposts.date_created
FROM
wallusers,wallusers as PosterTable, wallposts
LEFT JOIN walllikes_track
ON wallposts.p_id = walllikes_track.post_id AND walllikes_track.member_id = ".$user_id."
WHERE
wallusers.active = 1
AND
PosterTable.active = 1
AND
wallposts.group_id IN (".$groups.")
AND
wallposts.group_id != 0
AND
PosterTable.mem_id = wallposts.posted_by
AND
wallposts.marked < ".$this->flagNumber."
AND
wallusers.mem_id = wallposts.posted_by ) ";
The comments table is called wallcomments and it has a column called post_id. I know I need to use JOIN and COUNT but I don't know where to put it within my current code.
Try this query, I didn't run but i updated it.
SELECT wallposts.p_id,wallposts.is_profile_notes,wallposts.times_viewed,wallposts.columnTimesShared,
wallposts.marked,wallposts.secure_id,wallposts.reshared,wallposts.group_id,
wallposts.totaluploads,wallposts.WallUploadID,wallposts.type,
wallposts.value,wallposts.media,wallposts.youtube,wallposts.post_type,
wallposts.privacy,wallposts.tagedpersons,wallposts.with_friends_tagged,wallposts.emotion_head,wallposts.selected_emotion,wallposts.title,
wallposts.url,wallposts.description,wallposts.cur_image,
wallposts.uip,wallposts.likes,wallposts.userid,
wallposts.posted_by,wallposts.post as postdata,wallusers.*,
UNIX_TIMESTAMP() - wallposts.date_created AS TimeSpent,
PosterTable.mem_pic as posterPic, PosterTable.gender as posterGender,PosterTable.oauth_uid as poster_oauth_uid, PosterTable.username as posterUsername,
PosterTable.mem_fname as posterFname,PosterTable.work as posterWork,
PosterTable.mem_lname as posterLname,walllikes_track.id as PostLikeFound,wallposts.date_created
FROM
wallusers,wallusers as PosterTable, wallposts
WHERE
wallusers.active = 1
AND
PosterTable.active = 1
AND
wallposts.group_id IN (".$groups.")
AND
wallposts.group_id != 0
AND
PosterTable.mem_id = wallposts.posted_by
AND
wallposts.marked < ".$this->flagNumber."
AND
wallusers.mem_id = wallposts.posted_by ) " AND wallposts.p_id = walllikes_track.post_id AND walllikes_track.member_id = ".$user_id.";
A more readable query might look like this...
At least then we'd have a chance.
SELECT DISTINCT p.p_id
, p.is_profile_notes
, p.times_viewed
, p.columnTimesShared
, p.marked
, p.secure_id
, p.media...
FROM wallposts p...
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
UNION query with codeigniter's active record pattern
I have the following code:
$language_id=$this->get_language_id($language_code);
$english_id=$this->get_language_id('en');
$query="SELECT e.label_value, t.user_id, t.votes, t.approved, t.language_value FROM labels e left outer join labels t on e.label_value=t.label_value WHERE e.language=$english_id and t.language=$language_id and (t.approved=1 or t.user_id=$user_id) and e.label_value in (select distinct label_value from labels WHERE language=$english_id order by label_value limit $start_index, 30) order by e.label_value, t.votes";
$query=$this->db->query($query);
$data=$query->result_array();
But I have got the following error:
This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
So, I need to do the folowoing part "select distinct label_value from labels WHERE language=$english_id order by label_value offset $start limit 30" in another query. Please, help me, how can I do it using CodeIgniter?
UPDATE:
There are is table labels
(label_value, language_value, language) - PK,
user_id,
timestamp,
approved,
votes
and I need to get all queries from this table (for example, it's name is t and e) with labels t.label_value, e.label_value (is exists), e.user_id, e.votes, e.timestamp where t.label_value=e.label_value(same label), t.language=45 (english language), e.language=24 (my language) and (e.user_id=121234 or e.approved=1). But I need all entries, and if (t.label_value!=e.label_value) I need to get this entry with NULL fields.
This is a limitation of MySQL and not PHP or CI. In order to get around it, you need to wrap your sub query in an aliased sub query so it becomes a derived table:
$language_id = $this->get_language_id($language_code);
$english_id = $this->get_language_id('en');
$query = "
SELECT e.label_value, t.user_id, t.votes, t.approved, t.language_value
FROM labels e
LEFT OUTER JOIN labels t on e.label_value=t.label_value
WHERE
e.language = $english_id
AND t.language = $language_id
AND (t.approved = 1 OR t.user_id = $user_id)
AND e.label_value IN (
SELECT label_value
FROM (
SELECT DISTINCT label_value
FROM labels
WHERE language = $english_id
ORDER BY label_value
LIMIT $start_index, 30
) i
)
ORDER BY e.label_value, t.votes
";
$query = $this->db->query($query);
$data = $query->result_array();
I think that will work, let me know if it doesn't and I will take another look at it.
EDIT
I'm having a little difficulty working out exactly what you are trying to do, but I think it might be something more like this:
SELECT t.label_value, t.user_id, t.votes, t.approved, t.language_value
FROM (
SELECT DISTINCT label_value
FROM labels
WHERE language = $english_id
) e
LEFT JOIN labels t ON e.label_value = t.label_value
WHERE
t.language = $language_id
AND (t.approved = 1 OR t.user_id = $user_id)
ORDER BY t.label_value, t.votes
LIMIT $start_index, 30
If this is still not correct, please show some example rows, and the result set you would like to retrieve from those rows.
The following code is used in a query for fetching records. It uses the electors.ID to find the corresponding voting_intention.elector from a second table.
$criteria = "FROM voting_intention,electors WHERE voting_intention.elector = electors.ID AND voting_intention.pledge IN ('C','P') AND electors.postal_vote = 1 AND electors.telephone > 0"
The problem is that some electors will have more than one pledge in the voting_intentions table.
I need it to match only on the latest voting_intention.pledge based on the field votin_intention.date for each elector.
What is the simplest way of implementing that.
The rest of the code:
function get_elector_phone($criteria){
$the_elector = mysql_query("SELECT * $criteria ORDER BY electors.ID ASC"); while($row = mysql_fetch_array($the_elector)) {
echo $row['ID'].','; }
}
You could use a sub-select with the MAX() function. Add the following into your WHERE clause.
AND voting_intention.date = (select MAX(date)
from voting_intention vote2
where voting_intention.elector = vote2.elector)
Here is a SQLFiddle of the results.
So pretty much, you only want to bother looking at the most recent row that fits the first two criteria in your code. In that case, you would want to filter out the voting_intention table beforehand to only have to worry about the most recent entries of each. There's a question/answer that shows how do do that here.
Try selecting the following instead of voting_intention (from the answer of the linked question, some table and field names replaced):
SELECT voting_intention.*
FROM voting_intention
INNER JOIN
(
SELECT elector, MAX(date) AS MaxDate
FROM voting_intention
GROUP BY elector
) groupedintention ON voting_intention.elector = groupedintention.elector
AND voting_intention.date = groupedintention .MaxDate
Question url: How can I SELECT rows with MAX(Column value), DISTINCT by another column in SQL?