mysql - select from column with multiply values - mysql

I have this query
$r=mysql_query(
"SELECT *
FROM advertisements
WHERE
$filter exposure!='0' AND `status`='2' AND
(clicks_left_micro>0 OR clicks_left_mini>0
OR clicks_left_standard>0 OR clicks_left_extended>0
OR fixed='1')
ORDER BY
exposure DESC, fixed DESC"
);
In my advertisements table I have a column called geoFilter. That column can either be empty or it can contain values (country codes) like:
DK, US, CA, EN,
I get the users country code like this (stored in DB):
$userdata['country_code'];
My question is, how can I select from the advertisements table where users country code is present?

You can try to start your WHERE clause with: WHERE country_code LIKE „%US%“ AND (…) to get only results where US is contained in the country_code column.

Related

RoR: How to merge an order on two columns into an ActiveRecord query?

I'm trying to sort a table based on several columns so that the resulting order represents the fields interlaced.
ie,
users has first_name:string and last_name:string, account has historical_first_name, and historical_last_name, and belongs to User. If user has a first_name, it should override historical_first_name when listing accounts (ie, a user either has set their name or they have a historical name on an account).
I'm trying to return an ordered list of accounts based on first name and last name ASC, either historical or set on the user. The result should be an ActiveRecord relation and not an array.
This query does not achieve what I want:
#accounts = #accounts.includes(:user).order("users.first_name ASC, historical_first_name ASC, users.last_name ASC, users.last_name ASC")
Because any historical_first_names are that are alphabetically before first_names are sorted after all first_name. How would you write something that achieves an order like this:
Amanda Adams <- migration_first_name: Amanda, user.first_name: nil
Bentley James <- migration_first_name: nil, user.first_name: Bentley
Cynthia Cann <- migration_first_name: Cynthia, user.first_name: nil
You want to order primarily by the first_name, or the historical_first_name if that is null. And then after that order by last_name, or historical_last_name if that is null.
You can use the COALESCE() function (or IFNULL()) to represent that.
#accounts = #accounts.includes(:user).order(
"COALESCE(users.first_name, users.historical_first_name) ASC",
"COALESCE(users.last_name, users.historical_last_name) ASC"
)

When i try to display the count value of one column it counts the no. of arrays stored in a single cell of the same row on the same table

I have written the following function to display a table consisting of
recipe name, description, cusine , ........ ..., ingredients AND LIKES.
Everything works fine but the likes column doesnot show the no. of likes bu instead sows the no. of ingredients of the recipe
public function rec(){
$ing = inglist::all();
$rcusine=recipecusine::all();
$rtype=recipetype::all();
$rec = DB::table('recipe_list')
->select('recipe_list.recipe_id','recipe_list.Recipe_name',
'recipe_list.Recipe_desc','recipe_list.Recipe_duration',
DB::raw('group_concat(ing_list.Ing_name separator ",") as recipe_ingredients'),
'recipe_cusine.Cusine_name', 'recipe_type.Recipe_type_name','recipe_list.image',
DB::raw('count(likerecipes.likecount) as likes'))
->join('recipe_inglist', 'recipe_list.recipe_id','=','recipe_inglist.Recipe_id')
->join('ing_list', 'recipe_inglist.Ing_id','=','ing_list.ing_id')
->join('recipe_cusine', 'recipe_list.Recipe_cusine_id','=','recipe_cusine.cusine_id')
->join('recipe_type', 'recipe_list.Recipe_type_id','=','recipe_type.Recipe_typeID')
->join( 'likerecipes', 'recipe_list.recipe_id', '=', 'likerecipes.recipe_id')
->where('recipe_list.recipe_id','>=','1')
->groupBy('recipe_list.recipe_id', 'recipe_list.recipe_name','recipe_list.recipe_desc','recipe_list.recipe_duration', 'recipe_cusine.Cusine_name','recipe_type.Recipe_type_name','recipe_list.image' )->get() ;
/* var_dump($rec);
die();*/
return view('recipe', ['ingredients'=>$ing, 'cusine'=>$rcusine, 'type'=>$rtype,'recipe'=>$rec]);
}
the output i get is
and this is my likerecipes table
can anyone help me where i am wrong.
Because of the joins, your data is duplicated through the records. Since the likerecipes table seems to store like votes casted one by one identified by an id field uniquely, I would count the distinct likerecipes.id values per group:
'count(distinct likerecipes.id) as likes'
I would also introduce the distinct to the group_concat() to make sure that multiple like votes do not make the same ingridients appear multiple times:
'group_concat(distinct ing_list.Ing_name separator ",") as recipe_ingredients'

MySQL query copying data from one table to another randomly

I have this existing sql query that is working quite fine. It searches in a table called qu_pap_users under a particular field (userid) and then randomly grabs a userid to copy into a different table called settings...
$sql = "REPLACE INTO qu_g_settings (settingid, name, value)
SELECT '9038fa14', 'assignNonReferredAffiliateTo', qu_pap_users.userid
FROM qu_pap_users ORDER BY RAND() LIMIT 1";
I would like to change the last part of the query so that it does the following:
Locate the userid field as above, but now it needs to look into an additional field called data12.
I want it to only copy userids where the data12 field = Affiliate Distributor Licensed
After it has found all userids with a data12 field that = Affiliate Distributor Licensed, I would like it to then randomly select from those userids only.
I hope this is clear enough. Thank you in advance...
Try this, You have to just add where clause to filter data12 field = Affiliate Distributor Licensed
$sql = "REPLACE INTO qu_g_settings (settingid, name, value)
SELECT '9038fa14', 'assignNonReferredAffiliateTo',
qu_pap_users.userid
FROM qu_pap_users
WHERE qu_pap_users.data12 = 'Affiliate Distributor Licensed'
ORDER BY RAND() LIMIT 1";

where clause in COUNT function and joining two queries

I have a table that I am trying to count the number of course passed, and also list the modules passed as well.
The first problem I am having is what to put in the where variable, so that its not specific to a customer(I can use the query below for a particular customer and a particular course)but I will like a generic query where the result will be distinct in terms of user and course like the one below
SELECT FirstName
,LastName
,CourseTitle
,Noofmodules
,count(Coursecompleted) AS modulescompleted
FROM EStudentsprogress
WHERE Coursecompleted = '1'
AND EmailAddress = 'scascsc#e.co.uk'
AND CourseTitle = 'Microsoft MOS 2010 EXCEL'
GROUP BY FirstName
,LastName
,CourseTitle
,Noofmodules
How can I make it list the result as above, whereby I don't specify the email address or course title(trying to get the result for all the clients )
Also I have a query that list the courses that is passed by the customer, I will like the column with the list of courses passed be added to the result above, but as a column for each course.
SELECT FirstName
,LastName
,CourseTitle
,EmailAddress
,CourseModule AS coursepassed
FROM EStudentsprogress
WHERE coursecompleted = 1
Cheers
Can you not just add the email address and course title fields to the select fields and the GROUP BY clause.
Also you can use GROUP_CONCAT to bring back a field containing all the course modules.
Something like this:-
SELECT FirstName,
LastName,
CourseTitle,
Noofmodules,
EmailAddress,
CourseTitlecount,
COUNT(Coursecompleted) as modulescompleted,
GROUP_CONCAT(CourseModule) as modulescompletednames
FROM EStudentsprogress
WHERE Coursecompleted = '1'
GROUP BY FirstName, LastName, CourseTitle, Noofmodules, EmailAddress, CourseTitlecount ;

Is there a way to identify those records not found within a where IN() statement?

From PHP Code $Lines is defined as a list of accessions e.g. 123,146,165,1546,455,155
plant table has sequential records with the highest idPlant (unique identifier) of say 1000.
My simple SQL Query:
SELECT * FROM plant WHERE `plant`.idPlant IN($Lines) order by plant.idPlant;
This brings back row data for '123,146,165' etc.
Is there away to be told that '1546' was not found? (and thus the user probably entered a typo, I can not use a 'confirm all numbers are below X' because in the real data the idPlant may not be sequential and the upper bound will increase during use).
Update:
Looking to get an output that will tell me what Numbers were not found.
You can build up a sub query using unions that returns a list of all your values, then LEFT JOIN against that, checking for NULL in the WHERE clause to find the non matching values.
Basic php for this would be something like this:-
<?php
$sub_array = explode(',', $Lines);
$sub = '(SELECT '.implode(' AS i UNION SELECT ', $sub_array).' AS i) sub0';
$sql = "SELECT sub0.i
FROM $sub
LEFT OUTER JOIN plant
ON plant.idPlant = sub0.i
WHERE plant.idPlant IS NULL";
?>
You can create a temporary table and compare it to the original table. It goes something like this:
CREATE TEMPORARY TABLE IF NOT EXISTS plantIDs (
ID INT(11) NOT NULL UNIQUE,
found INT(11) NOT NULL);
INSERT INTO plantIDs(ID) VALUES (123),(146),(165),(1546),(455),(155);
SELECT plantIDs.ID, COALESCE(plant.name, "Not Found") as PlantName, plant.* FROM plant RIGHT JOIN plantIDs ON plant.idPlant=plantIDs.ID ORDER BY plantIDs.ID;
Assuming you have a field named name inside the table plant, this code will produce a row for each plant and the column named PlantName will contain the name of hte plant or the text "Not Found", ofc you can change the coalesce value to anything that fits your needs.