mySQL multiple results into one result row - mysql

I have a table that stores image URLs by product id and am trying to write a query that will pull all image results onto one line. The table looks something like:
photoFlag photoName objectID
where photoName holds the relative path to the image and photoFlag identifies the type of image (full, thumb, etc). I started off by writing a quick query to get two images (with different flags) to pull up. This is what I have:
select t2.pic, t4.pic, t2.id from
(select p2.photoName as pic, p2.objectID as id from ds_photos as p2 where p2.photoFlag = 2) as t2,
(select p4.photoName as pic, p4.objectID as id from ds_photos as p4 where p4.photoFlag = 4) as t4
where t2.id=t4.id
which seems to be a correct query but when I execute via phpMyAdmin it never returns a result and shows up indefinitely (well, at least for about 40 min) in the "SHOW PROCESS" list. Is there something that I have wrong that I'm not seeing in here that is causing an endless loop?
Ideally I would like grab only pics with photoFlag=2 (some products have multiple images) and put them into the same row but I have no idea where to start with that. Any suggestions?
Thanks for the help.

Use: GROUP_CONCAT:
SELECT id, GROUP_CONCAT(photoName ) As pic
FROM ds_photos
WHERE (photoFlag = 2 or photoFlag = 4) and id = ?;
GROUP BY id
replace the ? with the ID you want.

Related

ID lost after left join on table

Hey I tried this thread but it doesn't work and i can't figure out why...
here's my SQL:
SELECT * FROM gone_items
LEFT JOIN items
ON gone_items.item_ID=items.ID
WHERE
gone_items.aus_ID='$ID'
ORDER BY items.name ASC
Now, I fetch that via PHP and have a $row and try another mysql to get the individual ID's of the gone_items table. But if i use $row['ID'] I get the ID of the items.ID not the one from gone_items.ID.
I tried setting the variable manually in the first query but it doesn't work.
I also tried this: MYSQL Left join A.table and b.table while retaining a.table id
Also didn't help me...
All I want is to retain the ID (Primary key) from the gone_items table..
Can anyone please tell me what I'm doing wrong ?
Love
Gram
EDIT
//Query for Joined infos
$sqlx="SELECT foto_res_ausgeliehene_geg.ID, foto_res_ausgeliehene_geg.aus_ID, foto_res_ausgeliehene_geg.geg_ID, foto_res_ausgeliehene_geg.zusaetzliches, foto_res_gegenstaende.ID, foto_res_gegenstaende.bezeichnung, foto_res_gegenstaende.seriennummer, foto_res_gegenstaende.interne_seriennummer, foto_res_gegenstaende.zusaetzliches FROM foto_res_ausgeliehene_geg
LEFT JOIN foto_res_gegenstaende
ON foto_res_ausgeliehene_geg.geg_ID=foto_res_gegenstaende.ID
WHERE
foto_res_ausgeliehene_geg.aus_ID='$ID'
ORDER BY foto_res_gegenstaende.bezeichnung ASC
";
$ergebnisx = mysqli_query($db,$sqlx);
while ($zeilex = mysqli_fetch_assoc($ergebnisx))
{
//Query for individual infos
$sqly="SELECT * FROM foto_res_ausgeliehene_geg
WHERE `geg_ID`='".$zeilex['ID']."'
AND `aus_ID`='$ID'
GROUP BY `geg_ID`
";
$ergebnisy = mysqli_query($db,$sqly);
while ($zeiley = mysqli_fetch_assoc($ergebnisy))
{};
Now I did select all items individually. The foto_res_ausgeliehene_geg.ID still merges with the foto_res_gegenstanede.ID due to the LEFT JOIN.
So if i access $zeilex['ID'] im getting the ID of foto_res_gegenstaende.ID.
Would it help if I rename the ID field in one of the tables into lets say item_ID ?
Thanks alot.
Love
Gram.
Instead of using select *, you should explicitly state what items you want to select. Else you can get conflicts with multiple id fields. In your case something like:
select gone_items.id, gone_items.column1, gone_items.column2, items.column1, items.column2
It is also considered good practice, to limit the amount of data there is being selected. But is meanwhile also a highly debateable what is the right way. Performance issue in using SELECT *?
WORKS!
I simply renamed one of the Primary ID keys to something else, in this case, one of them got ID -> item_ID. The other one still is ID that way the left join won't merge them.
yolo
EDIT
WORKING CODE
$sqlx="SELECT foto_res_ausgeliehene_geg.item_ID, foto_res_ausgeliehene_geg.aus_ID, foto_res_ausgeliehene_geg.geg_ID, foto_res_ausgeliehene_geg.zusaetzliches, foto_res_gegenstaende.ID, foto_res_gegenstaende.bezeichnung, foto_res_gegenstaende.seriennummer, foto_res_gegenstaende.interne_seriennummer, foto_res_gegenstaende.zusaetzliches FROM foto_res_ausgeliehene_geg
LEFT JOIN foto_res_gegenstaende
ON foto_res_ausgeliehene_geg.geg_ID=foto_res_gegenstaende.ID
WHERE
foto_res_ausgeliehene_geg.aus_ID='$ID'
ORDER BY foto_res_gegenstaende.bezeichnung ASC
";
$ergebnisx = mysqli_query($db,$sqlx);
while ($zeilex = mysqli_fetch_assoc($ergebnisx))
{
//Query for individual infos
$sqly="SELECT * FROM foto_res_ausgeliehene_geg
WHERE `item_ID`='".$zeilex['item_ID']."'
";
$ergebnisy = mysqli_query($db,$sqly);
while ($zeiley = mysqli_fetch_assoc($ergebnisy))
{

SQL query not working as expected | Duplicates and wrong results

HEyo folks.
alright, So i'm working on this little snippet of code here
SELECT
current.name,
current.status,
current.votes,
current.info,
current.votes_required,
current.sid as sid,
current.previous_required,
previous.sid as psid,
previous.status as status
FROM
systems as current
INNER JOIN
systems as previous
WHERE
(previous.status = 1 and current.previous_required = previous.status)
OR
(current.previous_required = 0)
'
Which Ideally I would like to show the results where either previous_required == 0 or where the previous_required's status == 1. However, for some reason, i keep either getting triple the results from my search (EG duplicates) or only a single result for the first one.
I'm pretty dang sure I know where i'm messing up (It's either the Inner Join or the OR statement). but I cannot seem to nail it down and fix the issue. Any input would be greatly appreciated.
You need to move the condition from where to join
SELECT
current.name,
current.status,
current.votes,
current.info,
current.votes_required,
current.sid as sid,
current.previous_required,
previous.sid as psid,
previous.status as status
FROM
systems as current
INNER JOIN
systems as previous
ON
(previous.status = 1 and current.previous_required = previous.status)
OR
(current.previous_required = 0)
It looks like you need to link the current records to their previous records somehow. Does your systems table have something like "previous_sid", which links a current record back to a previous one? If so, you need to use that in you inner join. Something like:
FROM
systems AS current
INNER JOIN
systems AS previous on current.previous_sid = previous.sid

Trouble with MySQL query

OK, first-off I admit MySQL Syntax has never been my strongest point. So, here I am.
Urls :
ID Url Code
===============================================
1 http://www.google.com Abcd
2 http://www.freetemplates4u.com Efgh
3 ...
Posts :
ID Title Address
===============================================
1 Some Title 1 http://mize.it/Abcd
2 Some Title 2 http://mize.it/Efgh
3 ...
I want to create a query to fetch the following table
Title Url
=======================================================
Some Title 1 http://www.google.com
Some Title 2 http://www.freetemplates4u.com
In a few words :
Take the Url-Code pairs from Urls table
Search for http://mize.it/+Code in the Posts table (in the Address field)
Combine the final Title and Url in a result table.
I know it has something to do with joins and concatenation, but I'm definitely lost.
SIDENOTE : I don't care neither about my current database's structure, nor about performance issues. All I want is to transfer existing data, from the existing database (without having to alter it), to my new website's database (under a totally different format/structure).
You should change your DB-Design, this query will have a poor performance since mysql has to do a full tablescan.
Try adding a code column in your Posts table hat has the right value (populate it on insert/update) and add an index to Code (both tables).
Now you should be able to do.
SELECT Posts.Title, Urls.Url
FROM Posts
INNER JOIN Urls ON Post.Code = Urls.Code
Update:
If the first part of the url is always the same, this will work
SELECT Post.Title, Urls.Url
FROM Posts
INNER JOIN Urls ON Post.Adress = CONCAT('http://mize.it/', Urls.Code)
TRY
SELECT p.title,x.url
FROM Posts p
INNER JOIN ( SELECT url, CONCAT('http://mize.it/',code) AS xcode FROM Urls ) x
ON (x.xcode = p.address)
Working DEMO
This is a different approch, it took a while for me to test it.
Since your Address field contains complete url and we only need to match what is after / so we can replace actual url with nothing (I assume url is always the same) and have string ready to be matched with Code field.
SELECT b.Title, a.URL
FROM Url a
LEFT JOIN Posts b
ON a.Code = REPLACE(b.Address, 'http://mize.it/', '')
ORDER BY a.ID ASC
Check following query.
select m1.Url, m2.Title from Urls as m1, Posts as m2
where m2.address like 'http://mize.it/%'

How can I sanitize my DB from these duplicates

I have a table with the following fields:
id | domainname | domain_certificate_no | keyvalue
An example for the output of a select statement can be as:
'57092', '02a1fae.netsolstores.com', '02a1fae.netsolstores.com_1', '55525772666'
'57093', '02a1fae.netsolstores.com', '02a1fae.netsolstores.com_2', '22225554186'
'57094', '02a1fae.netsolstores.com', '02a1fae.netsolstores.com_3', '22444356259'
'97168', '02aa6aa.netsolstores.com', '02aa6aa.netsolstores.com_1', '55525772666'
'97169', '02aa6aa.netsolstores.com', '02aa6aa.netsolstores.com_2', '22225554186'
'97170', '02aa6aa.netsolstores.com', '02aa6aa.netsolstores.com_3', '22444356259’
I need to sanitize my db such that: I want to remove the domain names that have repeated keyvalue for the first domain_certificate_no (i.e, in this example, I look for the field domain_certificate_no: 02aa6aa.netsolstores.com_1, since it is number 1, and has repeated value for the key, then I want to remove the whole chain which is 02aa6aa.netsolstores.com_2 and 02aa6aa.netsolstores.com_3 and this by deleting the domain name that this chain belongs to which is 02aa6aa.netsolstores.com.
How can I automate the checking process for the whole DB. So, I have a query that checks any domain name in the pattern ('%.%.%) EDIT: AND they have share domain name (in this ex: netsolstores.com) , if it finds cert no. 1 that belongs to this domain name has a repeated key value, then delete. Otherwise no. Please, note tat, it is ok for domain_certificate_no to have repeated value if it is not number 1.
EDIT: I only compare the repeated valeues for the same second level domain name. Ex: in this question, I compare the values that share the domain name: .netsolstores.com. If I have another domain name, with sublevel domains, I do the same. But the point is that I don't need to compare the whole DB. Only the values with shared domain name (but different sub domain).
I'm not sure what happens with '02aa6aa.netsolstores.com_1' in your example.
The following keeps only the minimum id for any repeated key:
with t as (
select t.*,
substr(domain_certificate_no,
instr(domain_certificate_no, '_') + 1, 1000) as version,
left(domain_certificate_no, instr(domain_certificate_no, '_') - 1) as dcn
from t
)
select t.*
from t join
(select keyvalue, min(dcn) as mindcn
from t
group by keyvalue
) tsum
on t.keyvalue = tsum.keyvalue and
t.dcn = tsum.mindcn
For the data you provide, this seems to do the trick. This will not return the "_1" version of the repeats. If that is important, the query can be pretty easily modified.
Although I prefer to be more positive (thinking about the rows to keep rather than delete), the following should delete what you want:
with t as (
select t.*,
substr(domain_certificate_no,
instr(domain_certificate_no, '_') + 1, 1000) as version,
left(domain_certificate_no, instr(domain_certificate_no, '_') - 1) as dcn
from t
),
tokeep as (
select t.*
from t join
(select keyvalue, min(dcn) as mindcn
from t
group by keyvalue
) tsum
on t.keyvalue = tsum.keyvalue and
t.dcn = tsum.mindcn
)
delete from t
where t.id not in (select id from tokeep)
There are other ways to express this that are possibly more efficient (depending on the database). This, though, keeps the structure of the original query.
By the way, when trying new DELETE code, be sure that you stash a copy of the table. It is easy to make a mistake with DELETE (and UPDATE). For instance, if you leave out the WHERE clause, all the rows will disappear, after the long painful process of logging all of them. You might find it faster to simply select the desired results into a new table, validate them, then truncate the old table and re-insert them.

Linq Group on a multi-level object with select statement

I've got 3 dataset objects that are nested with each other using entity set objects. I am selecting the data like this
var newList = from s in MainTable
from a in s.SubTable1 where a.ColumnX = "value"
from b in a.Detail where b.Name = "searchValue"
select new {
ID = s.ID,
Company = a.CompanyName,
Name = b.Name,
Date = s.DueDate
Colour = b.Colour,
Town = a.Town
};
and this works fine, but the trouble is there are many records in the Detail object-list/table for each Name value so I get a load of duplicate rows and thus I only want to display one record per b.Name. I have tried putting
group s by b.Name into g
before the select, but then this seems to stop the select enabling me to select the columns I want (there are more, in practice). How do I use the group command in this circumstance while still keeping the output rows in a "flat" format?
Appending comment as answer to close question:-
Of course that if you group your results, you cant get select a column of a child, thats because there may be more than one childs and you have to specify an aggregate column for example the sum,max etx –