date variables in JOINed SELECT statements - mysql

$sql = 'SELECT have_show FROM `date` WHERE DATE(`date`.day) = ?';
$this->db->query($sql, array($date)); //works fine
This works fine as expected.
$sql = 'SELECT actors, visitors, tickets, have_show FROM show
JOIN `date` ON show.day = `date`.id
WHERE DATE(`date`.day) = ?';
$this->db->query($sql, array($date));
here, with joined statements it gives 0 results.
db schema
id(AI) day(INT FK-date.id) actors(INT) visitors(INT)
1 2 3 45
id(AI) day(DATE) have_show(BOOLEAN)
1 2012-12-06 0
2 2012-12-07 1
codeigniter's active records does the same.
Any of you ever suffered from this kind of poblems?

try this one
$sql = 'SELECT actors, visitors, tickets, acts FROM `show`
JOIN `date` ON show.day = date.id
WHERE DATE(date.day) = ?';
$this->db->query($sql, array($date));
you have mixed between date.day and date.id.
or maybe u have show.id not show.day so look what u have in your table and if yes
replace in your sql show.day by show.id
EDIT:
$sql = 'SELECT s.day s.actors, s.visitors, s.tickets, s.acts d.day FROM `show` s
JOIN `date` d ON s.day = d.id ';

Related

Convert mysql sub query to Laravel

How I can convert mysql query to laravel query? this is the query
SELECT
users.first_name,
users.id AS uid,
(
SELECT
COUNT(vpl_submissions.accept)
FROM
vpl_submissions
INNER JOIN vpl ON vpl_submissions.vpl = vpl.id
WHERE vpl.courseid = 2
AND vpl_submissions.accept = 1
AND vpl_submissions.userid = uid
) AS completed
FROM
users
INNER JOIN course_enroles ON users.id = course_enroles.user_id
WHERE course_enroles.course_id = 2
You can try this.
DB::table('users')
->join('course_enroles', 'users.id', '=', 'course_enroles.user_id')
->where("course_enroles.course_id", "=", 2)
->select(users.first_name,users.id AS uid,
DB::raw("(SELECT COUNT(vpl_submissions.accept) FROM
vpl_submissions INNER JOIN vpl ON vpl_submissions.vpl = vpl.id
WHERE vpl.courseid = 2
AND vpl_submissions.accept = 1
AND vpl_submissions.userid = uid) as completed")
)
->get();
This will help you.
Until you find a better solution, you can run raw queries like this
$result = DB::select(DB::raw("
select users.first_name,users.id AS uid,
(
select count(vpl_submissions.accept)
FROM vpl_submissions
INNER JOIN vpl on vpl_submissions.vpl = vpl.id
WHERE vpl.courseid=2 AND vpl_submissions.accept =1
AND vpl_submissions.userid = uid
) as completed
from users
inner join course_enroles on users.id = course_enroles.user_id
where course_enroles.course_id = 2
"));

how write sub-query with having clause in cakephp 3

How to write following query in CakePHP 3. It has "having" clause in sub-query
the following query is working but what is the way to write CakePHP query for following complex query.
$query = "SELECT users.name, users.Id ,users.primary_image ,genders.name as genderName, FLOOR(DATEDIFF(CURDATE(),users.DOB) / 365) AS age, countries.Name as countryName, states.Name as stateName,
user_log.online_status
FROM users_address, genders , countries, states, user_log , users
WHERE gender_id = " . $looksFor->gender_id ."
AND Users_address.user_id = users.Id
AND genders.Id = users.gender_id
AND Users_address.country_id = countries.Id
AND Users_address.state_id = states.Id
AND user_log.user_id = users.Id
AND users.Id IN (
SELECT users_responses.user_id
FROM users_responses
WHERE". $conditions_list ."
GROUP BY user_id
HAVING COUNT(DISTINCT question_id, response_id) > ".$thirty_percent." );
ORDER BY RAND()
LIMIT 15 ";
}
$thirty_percent and $conditions_list have the following data which is used in sub-query to find out the results.
$thirty_percent = (int)($conditions_count/3.3 );
$conditions_list = (question_id = 3 AND response_id = 6)OR
(question_id = 5 AND response_id = 8)OR
(question_id = 12 AND response_id = 33)OR
(question_id = 6 AND response_id = 17)OR
(question_id = 9 AND response_id = 26)OR
(question_id = 7 AND response_id = 18)OR
(question_id = 1 AND response_id = 5)OR
(question_id = 8 AND response_id = 22)OR
(question_id = 2 AND response_id = 3)
EDIT:
I learnt first write sub query and then put that query in main query
Main Query: $this->Users->find('all',[
'contain'=>['Genders','Images','Users_Address', 'Countries','States'],
'conditions'=>[ 'user_id IN' => $Subquery ]
]);
Sub Query :
$Subquery = $UsersResponses->find('all',[
'conotain'=>[],
]])->where([$conditions_list, **here problem 1** ])->group('user_id')->having COUNT("(DISTINCT question_id, response_id)=>" = ".$thirty_percent." )here problem 2 ;
SQL sub-Query
SELECT users_responses.user_id
FROM users_responses
WHERE". $conditions_list ."
GROUP BY user_id
HAVING COUNT(DISTINCT question_id, response_id) > ".$thirty_percent." );
ORDER BY RAND()
LIMIT 15 ";
As you see in sub-query I need to put $conditions_list which have arrays of conditions and how we can put here in CAKEPHP.
problem 2 :need to use
GROUP BY user_id
HAVING COUNT(DISTINCT question_id, response_id) > ".$thirty_percent." );
ORDER BY RAND()
LIMIT 15 "; in sub-query but there is no clue how to do it.

Long tail where clause at CodeIgniter or Ignited Datatables

I am trying to write a long tail where statement which containing another select query and how I can do it. Currently, I am using Ignited Datatables Library with my CodeIgniter 3 installation.
SELECT ContactId,
ReceiverId,
SenderId,
IF(ReceiverId = 1,
(SELECT first_name
FROM users
WHERE users.id = contacts_connectivity.SenderId),
(SELECT first_name
FROM users
WHERE users.id = contacts_connectivity.ReceiverId)) AS FirstName,
IF(ReceiverId = 1,
(SELECT email
FROM users
WHERE users.id = contacts_connectivity.SenderId),
(SELECT email
FROM users
WHERE users.id = contacts_connectivity.ReceiverId)) AS SenderEmail,
IF(ReceiverId = 1,
(SELECT phone
FROM users
WHERE users.id = contacts_connectivity.SenderId),
(SELECT phone
FROM users
WHERE users.id = contacts_connectivity.ReceiverId)) AS SenderPhone,
IF(ReceiverId = 1,
(SELECT company
FROM users
WHERE users.id = contacts_connectivity.SenderId),
(SELECT company
FROM users
WHERE users.id = contacts_connectivity.ReceiverId)) AS SenderCompany,
ModulesId,
(SELECT ModuleName
FROM modules
WHERE ModuleId = contacts_connectivity.ModulesId) AS ModuledName,
FROM_UNIXTIME(AddedDate, "%m/%d/%Y") AddedDate
FROM contacts_connectivity
WHERE (ReceiverId = 1
OR SenderId = 1)
AND (ReceiverId
OR SenderId NOT IN
(SELECT (ReceiverId
OR SenderId)
FROM contacts_connectivity
WHERE (ReceiverId
OR SenderId) = 1))
I noticed that My query doesn't return any array at all. I already tried to write the where statement like this-
$this->datatables->where("(ReceiverId = ' . $id . ' OR SenderId = ' . $id . ')");
$this->datatables->where(" AND (ReceiverId OR SenderId NOT IN (SELECT (ReceiverId OR SenderId) FROM contacts_connectivity WHERE (ReceiverId OR SenderId) = ' . $id . '");
What am I doing wrong?
You invalid use parameters. Try something like this:
$this->datatables->where("(ReceiverId=$id OR SenderId=$id )");
Second string should be fixed too the same way. Also check that your $id param properly escaped.

LEFT JOIN with exceptions

Here's my current query:
$q = "SELECT u.uid,CONCAT_WS(' ', u.first_name, u.last_name) name, CASE WHEN t.name IS NULL THEN 0 ELSE t.name END AS teamname ";
$q .= "FROM {$users} ";
$q .= "LEFT JOIN {$schedule} ON u.uid = s.uid ";
$q .= "LEFT JOIN {$products} ON p.admitting_id = u.uid ";
$q .= "LEFT JOIN {$teams} ON t.id = s.team ";
$q .= "WHERE (u.uid = {$current_user_id} AND u.roles = 'hoa') OR ";
$q .= "(p.id={$pid} AND p.admitting_id != 0) OR ";
$q .= "(t.admitting = 1 AND s.inactive != 1 AND s.role = 'hoa' AND (s.date = '{$today}' OR (s.date = '{$yesterday}' AND t.overnight = 1))) ";
$q .= "ORDER BY u.last_name,u.first_name,t.name";
What I need to get is:
Current User, if Current User has role hoa
User where uid matches admitting_id from products table
All users with role hoa who are scheduled today or were scheduled yesterday on an overnight shift. With those scheduled users, I need the names of the team they were/are scheduled with. Duplicate uids is good because I need all the different team names if they were scheduled on multiple teams.
What I don't need to get is:
Team name for options 1 and 2 above.
What I'm getting is:
Everything perfect for #3 above.
All possible team names for #1 and #2 above, whereas I want the team names to be 0 if they're not on the schedule.
I could split this up into three queries but that's not preferable.
Sometimes formatting the query out a bit helps visualise. It doesn't need to become three queries, I agree.
Can you provide some sample schema and data, ideally both in the question description and on something like sqlfiddle for us to play with?
It's hard to visualise your structure and data, but I'm speculating the issue is every record in users table is joining to schedule with the on clause you've used.
You could move the logic of condition 3 into the on clause (it's a left join, so nothing else will break) or duplicate it in the CASE statement in the SELECT:
$q = <<<SQL
SELECT
u.uid,
CONCAT_WS(' ', u.first_name, u.last_name) name,
IF(
WHEN t.name IS NULL THEN
0
ELSE
t.name
END AS teamname
FROM {$users} AS u
LEFT JOIN {$schedule} AS s ON (u.uid = s.uid)
LEFT JOIN {$products} AS p ON (p.admitting_id = u.uid)
LEFT JOIN {$teams} AS t ON
(
t.id = s.team AND
t.admitting = 1 AND
s.inactive != 1 AND
s.role = 'hoa' AND
(
s.date = '{$today}'
OR
(
s.date = '{$yesterday}' AND
t.overnight = 1
)
)
)
WHERE
( -- 1: Current User, if Current User has role hoa
u.uid = {$current_user_id} AND
u.roles = 'hoa'
)
OR
( -- 2: User where uid matches admitting_id from products table
p.id={$pid} AND
p.admitting_id != 0
)
OR
t.name IS NOT NULL
ORDER BY
u.last_name,
u.first_name,
t.name
SQL;
I'm absolutely not certain that'll fix your problem without something real to play with... Happy to continue looking if you can provide a working example sandpit.

MySQL - combining multiple queries

I currently have the following queries (and some surrounding vB code). I was hoping I could slim this up into a single SELECT statement versus having to run 10 more on each page to get that names of individuals.
$results = $db->query_read_slave("
SELECT user.id AS steam, user.skills AS level
FROM wcsp.wcgousers AS user
WHERE race = '_wcs_'
ORDER BY ABS(user.skills) DESC LIMIT 10
");
$rank = 1;
while ($user = $db->fetch_array($results)) {
$result = $db->query_first("
SELECT old.name AS name
FROM wcsp.warn_oldnames AS old
WHERE id = '$user[steam]'
ORDER BY lasttime
DESC LIMIT 1
");
$listing[] = array("id" => $user['steam'], "level" => $user['level'], "name" => $result['name'], "rank" => $rank);
$rank += 1;
}
I have tried LEFT JOIN but the issue I run into is that I would need a subquery in the LEFT JOIN similar to:
SELECT user.id AS steam, user.skills AS level, names.name AS name
FROM wcsp.wcgousers AS users
LEFT JOIN
(
SELECT names.name
FROM wcsp.warn_oldnames AS names
WHERE id = wcsp.wcgousers.id
ORDER BY lasttime DESC LIMIT 1
) AS names
ON names.id = users.id
WHERE users.race = '_wcs_'
Which won't work due to the different database check inside the subquery.
If I understand you correctly, you want to get the latest Name for every users.
SELECT a.id AS steam,
a.skills AS level,
b.name
FROM wcgousers a
INNER JOIN warn_oldnames b
ON a.ID = b.ID
INNER JOIN
(
SELECT ID, MAX(lasttime) max_date
FROM warn_oldnames
GROUP BY ID
) c ON b.ID = c.ID AND
b.lastTime = c.max_date
WHERE a.race = '_wcs_'
-- ORDER BY ABS(a.skills) DESC
-- LIMIT 10