can't get select query to work - mysql

I want to use a Select query from mysql database in C:
mysql_query(conn,"SELECT SI AS SUBSCRIBER_ID ,TG2 AS TAG_ID, SUM(CTR) AS NBR FROM (SELECT H.SUBSCRIBER_ID AS SI, TG.TAG_ID AS TG1,T.TAG_ID AS TG2, COUNT(TG.TAG_ID) AS COUNTER,CASE WHEN (TG.TAG_ID = T.TAG_ID) THEN COUNT(TG.TAG_ID) ELSE 0 END AS CTR from content_hits H left join CONTENT_TAG TG ON TG.CONTENT_ID = H.CONTENT_ID LEFT JOIN TAG T ON 1= 1 GROUP BY H.SUBSCRIBER_ID, TG.TAG_ID,T.TAG_ID) AS TAB GROUP BY SI,TG2");
After that, I want to use 'NBR' to fill an array of one dimension.
I tried this:
result = mysql_store_result(conn);
while ((row = mysql_fetch_row(result)))
{
t[i]=*row['NBR'];
printf("%d",t[i]);
}
But it didn't work.

You cannot access the row columns by name like you have t[i]=*row['NBR'];. Use for example fields = mysql_fetch_fields(result); to get the column names and iterate through the fields array to find which column id 'NBR' has. This id can then be used in t[i]=row[id];. This is all in the mysql connectors doc http://dev.mysql.com/doc/refman/5.0/en/mysql-fetch-fields.html

Related

select by columns multiple criteria

I have this db structure
and this is my joined tables (sample data)
i want to filter when (key = 'price' and value > 4000) and (key = 'top-speed' and value > 200)
thanks for help)
Try this:
SELECT
car.id,
car.name,
key,
value
FROM
car c
LEFT JOIN car_specification_value csv ON c.id = csv.car_id
LEFT JOIN specification s ON csv.specification_id = s.id
WHERE
s.key = 'price'
AND csv.value > 4000
AND s.key = 'top-speed'
AND csv.value > 200;
A common practice is giving aliases to your tables so the join conditions can be determined in a shorter way.
One method uses aggregation:
select csv.car_id
from car_specification_value csv
where (csv.key = 'price' and (csv.value + 0) > 4000) and
(csv.key = 'top-speed' and (csv.value + 0) > 200)
group by csv.car_id
having count(distinct csv.key) = 2; -- both match
Note the + 0. This uses implicit conversion to change the value to a number, so it can be properly compared to a number. One challenge of key/value data structures is that all the values are strings, and that is tricky for other data types.

Mysql - How to use field data as POINT() function

I have a sql like this:
SELECT
userAddress.user_address_complete,
userAddress.user_address_point,
deliveryZone.delivery_zone_id,
St_contains(deliveryZone.delivery_zone_polygon,
Geomfromtext('POINT(userAddress.user_address_point)')) AS cnt
FROM user_addresses userAddress
LEFT JOIN delivery_zones deliveryZone
ON (deliveryZone.restaurants_id = 154
AND St_contains(deliveryZone.delivery_zone_polygon,
Geomfromtext('POINT(userAddress.user_address_point)'))
> 0)
WHERE userAddress.user_address_user_id = 1
problem is that POINT(userAddress.user_address_point) should use userAddress.user_address_point field data, but sql can't understand that it is a field name and behave with it like a string so we have not result.
any suggestion?
Try to exclude column name from string. Split it into
'POINT('userAddress.user_address_point'))
SELECT
userAddress.user_address_complete,
userAddress.user_address_point,
deliveryZone.delivery_zone_id,
St_contains(deliveryZone.delivery_zone_polygon,
Geomfromtext('POINT('userAddress.user_address_point')')) AS cnt
FROM user_addresses userAddress
LEFT JOIN delivery_zones deliveryZone
ON (deliveryZone.restaurants_id = 154
AND St_contains(deliveryZone.delivery_zone_polygon,
Geomfromtext('POINT('userAddress.user_address_point')'))
> 0)
WHERE userAddress.user_address_user_id = 1

Slow mySql update containing Join

I have a system that collects data from production reports (CSV files) and puts them into a mySql DB.
I have an header table, that contain the production data of sequential report with same setting, and a table with the single reports, connected to the first one (trfCamRep.hdrId -> trfCamHdr.id).
I have a query to calculate the total report, the dubt and the faulty, and the maxTs. These datas are used in the visualizator.
The query is too slow, it requires 9sec.
Can you help me to speed up it?
SET #maxId:=(SELECT MAX(id) FROM trfCamHdr WHERE srcCod='7');
UPDATE trfCamHdr AS hdr
LEFT JOIN (SELECT hdrF.id,COUNT(*) AS nTot,
SUM(IF(res=1,1,0)) AS nWrn,SUM(IF(res=2,1,0)) AS nKO,
MAX(ts) AS maxTS
FROM trfCamHdr AS hdrF
JOIN trfCamRep AS repF ON repF.hdrId=hdrF.id
WHERE clcEnd=0 AND srcCod='7'
GROUP BY hdrF.id) AS valT ON valT.id=hdr.id
SET hdr.clcEnd=IF(hdr.id<#maxId,1,0),
hdr.nTot=valT.nTot,
hdr.nWrn=valT.nWrn,
hdr.nKO=valT.nKO,
hdr.maxTS=valT.maxTS
WHERE hdr.id>=0 AND hdr.clcEnd=0 AND hdr.srcCod='7';
Note trfCamHdr has these columns:
id (primary key)
clcEnd : flag of end calculation (the last remain to 0 because in progress)
nTot : elements with this header
nWrn : elements with res = 1
nKO : elements with res = 2
maxTs : TS of the last element
trfCamRep has these columns:
hdrId (refer to id of trfCamHdr)
res : 0 good, 1 dubt, 2 fault
ts : report timestamp
I'd take this out:
SET #maxId:=(SELECT MAX(id) FROM trfCamHdr WHERE srcCod='7');
And any allusions to the MaxId variable, I believe it to be redundant.
Everything you do will be lower than the max id, and it will take time to calculate if its a big table. You are already checking for srcCod = 7, so it isn't necessary.
In fact, it would miss the update on the one with the actual max id, which is not what I believe you want.
Your left join will also update all other rows in the table with NULL, is that what you want? You could switch that to an inner join, and if your rows are already null, they will just get left alone, rather than getting updated with NULL again.
Then you could just switch out this:
SET
hdr.clcEnd = IF(hdr.id < #maxId, 1, 0),
To
SET
hdr.clcEnd = 1,
Here is the rewritten thing, as always, back your data up before trying:
UPDATE trfCamHdr AS hdr
INNER JOIN
(SELECT
hdrF.id,
COUNT(*) AS nTot,
SUM(IF(res = 1, 1, 0)) AS nWrn,
SUM(IF(res = 2, 1, 0)) AS nKO,
MAX(ts) AS maxTS
FROM
trfCamHdr AS hdrF
JOIN trfCamRep AS repF ON repF.hdrId = hdrF.id
WHERE
clcEnd = 0 AND srcCod = '7'
GROUP BY hdrF.id) AS valT ON valT.id = hdr.id
SET
hdr.clcEnd = 1,
hdr.nTot = valT.nTot,
hdr.nWrn = valT.nWrn,
hdr.nKO = valT.nKO,
hdr.maxTS = valT.maxTS
WHERE
hdr.id >= 0 AND hdr.clcEnd = 0
AND hdr.srcCod = '7';
I found the solution: I created a KEY on hdrId column and now the query requires 0.062s.

Excluding a value from the return result of MySQL

I'm facing a problem and I'm not finding the answer. I'm querying a MySql table during my java process and I would like to exclude some rows from the return of my query.
Here is the query:
SELECT
o.offer_id,
o.external_cat,
o.cat,
o.shop,
o.item_id,
oa.value
FROM
offer AS o,
offerattributes AS oa
WHERE
o.offer_id = oa.offer_id
AND (cat = 1200000 OR cat = 12050200
OR cat = 13020304
OR cat = 3041400
OR cat = 3041402)
AND (oa.attribute_id = 'status_live_unattached_pregen'
OR oa.attribute_id = 'status_live_attached_pregen'
OR oa.attribute_id = 'status_dead_offer_getter'
OR oa.attribute_id = 'most_recent_status')
AND (oa.value = 'OK'
OR oa.value='status_live_unattached_pregen'
OR oa.value='status_live_attached_pregen'
OR oa.value='status_dead_offer_getter')
The trick here is that I need the value to be 'OK' in order to continue my process but I don't need mysql to return it in its response, I only need the other values to be returned, for the moment its returning two rows by query, one with the 'OK' value and another with one of the other values.
I would like the return value to be like this:
'000005261383370', '10020578', '1200000', '562', '1000000_157795705', 'status_live_attached_pregen'
for my query, but it returns:
'000005261383370', '10020578', '1200000', '562', '1000000_157795705', 'OK'
'000005261383370', '10020578', '1200000', '562', '1000000_157795705', 'status_live_attached_pregen'
Some help would really be appreciated.
Thank you !
You can solve this with an INNER JOIN on the self I think:
SELECT o.offer_id
,o.external_cat
,o.cat
,o.shop
,o.item_id
,oa.value
FROM offer AS o
INNER JOIN offerattributes AS oa
ON o.offer_id = oa.offer_id
INNER JOIN offerattributes AS oaOK
ON oaOK.offer_id = oa.offer_id
AND oaOK.value = 'OK'
WHERE o.cat IN (1200000,12050200,13020304,3041400,3041402)
AND oa.attribute_id IN ('status_live_unattached_pregen','status_live_attached_pregen','status_dead_offer_getter','most_recent_status')
AND oa.value IN ('status_live_unattached_pregen','status_live_attached_pregen','status_dead_offer_getter');
By doing a self-JOIN with the restriction of value OK, it will limit the result set to offer_ids that have an OK response, but the WHERE clause will still retrieve the values you need. Based on your description, I think this is what you were looking for.
I also converted your implicit cross JOIN to an explicit INNER JOIN, as well as changed your ORs to IN, should be more performant this way.

Update table using alias

I need to fill some fields in a table getting informations from other records of the same table.
I tried to write a query to explain what I want to do:
update globale2
set
nita = t.nita,
tita = t.tita,
notaita = t.notaita
where
neng = t.neng and
nita is null
(select nita, neng, tita, notaita from globale where uris='mma' and nita is not null) as t
edit to eplain better:
every records have these fields: "nita", "tita", "notaita", "neng" ("neng" cannot be null)
I want to fill these fields: "nita", "tita", "notaita" (where "nita" is empty)
with the same values from another record where "neng" equals the other "neng"
You can however, join the two tables.
UPDATE globale2 g
INNER JOIN globale gg
ON g.neng = gg.neng
SET g.nita = gg.nita,
g.tita = gg.tita,
g.notaita = gg.notaita
WHERE g.nita IS NULL
AND gg.uris = 'mma'
AND gg.nita IS NOT NULL
assume there is a table A_temp, with two columns 'one' and 'two'.
TABLE A_temp
ONE TWO
1 2
this is the present status of the table.
The query
UPDATE (SELECT * FROM A_temp ) A SET one = A.two where one = '1'
updates the table as
ONE TWO
2 2
Hope you get the idea and that it helps..