tags:

views:

62

answers:

4

Example DB structure (download table)

id | pid     | title
----------------------------------------------------
1  | 3,4,5   | Download 3, Download 4, Download 5
----------------------------------------------------
2  | 3       | Download 3
----------------------------------------------------

Here is my code

<?php
  $pid = explode(",",  $order['pid']);
  for($x = 0; $x < count($pid);){ 
  if(count($pid) == 1 ) {
  $thepid = 'pid="'.$pid[$x].'"';
  } else {
  $thepid = 'pid="'.$pid[$x].'" OR ';
  }
$x++; }

$select = 'SELECT * FROM download WHERE '.$thepid.'';
$query = $db->rq($select);
while($download = $db->fetch($query)) {
?>

Question -

  1. How to make the $select can read pid="3" OR pid="4" OR pid="5" if count($pid) more than one.

I know the table structure is not normal. But how possible to get it works.

A: 

If you want to stick with this structure (which is not optimal if you want to make such queries), you can use LIKE:

SELECT * FROM download WHERE pid LIKE '%3%' OR pid LIKE '%4%' OR pid LIKE '%5%'

But you will get into trouble if you have numbers > 9.

I would really recommend to normalize your table!


Some comments on your code.

  1. Your for loop looks strange. Why do you increase $x at the end instead instead of defining this in the "head" of the loop?
  2. You are reassigning $thepid again and again in the for loop, so it will have the value of the last iteration.
  3. You are using count() too often.

Here is an improved version, but note, this does only works, if your table is normalized:

<?php
  $pids = explode(",",  $order['pid']);
  $conds = array();
  foreach($pids as $pid) {  
      $conds[] = 'pid="'.$pid.'"';
  }

  $conds = implode(' OR ', $conds);

  $select = 'SELECT * FROM download WHERE '.$cond.'';
  $query = $db->rq($select);
  while($download = $db->fetch($query)) {
Felix Kling
Thanks bro for the explanation. Will normalize the table later.
kampit
+1  A: 

Use REGEXP

SELECT * FROM download WHERE pid REGEXP '\\b(3|4|5|12)\\b'

If \\b is not supported, you can try:

SELECT * FROM download WHERE pid REGEXP '(^|,)(3|4|5|12)(,|$)'
Amarghosh
+1  A: 

This is not a really good way to represent your data.

I assume that your columns represent something like

id -> user_id

pid -> a list of all items downloaded by the user (comma-separated)

title -> a list of all items' names downloaded by the user (comma-separated)

The thing with this approach is that you will find that queries like this one are much harder to express than with a normal approach. For example:

Table Users

user_id

Table Files

pid

title

Table Downloads

user_id

pid

both as foreign key to the corresponding table

Your query would become

<?php
  $pid = explode(",",  $order['pid']);
  for($x = 0; $x < count($pid);){ 
  if($x == 0 ) {
  $thepid = 'pid='.mysql_real_escape_string($pid[$x]);
  } else {
  $thepid = 'OR pid='.mysql_real_escape_string($pid[$x]);
  }
$x++; }

$select = 'SELECT user_id FROM download WHERE '.$thepid.'';
$query = $db->rq($select);
while($download = $db->fetch($query)) {
?>
Lombo
Thanks for the explanation.
kampit
+1  A: 

Maybe I'm over-simplifying this a bit, but wouldn't this be easier?

<?php

$select = 'SELECT * FROM download WHERE pid IN ('.$order['pid'].')';
$query = $db->rq($select);
while($download = $db->fetch($query)){}
?>
jbudge
Thanks! Simple solutions at this time to keep the current structure.
kampit
@kampit: This should not work. I cannot see how `pid IN ('3','4','5')` can come true for `pid = '3,4,5'` , because the element `'3,4,5'` is not in the set. Does this really work for you?
Felix Kling
The SQL query returned by my example would look something likeSELECT * FROM download WHERE pid IN (3,4,5);WHERE/IN takes an array. The string concatenation used when building the query will make it an acceptable format so mysql reads it as an array.And it doesn't need to be the same order.Having pid="5,3,4" is still solved by very simple, elementary level SQL.SELECT * FROM download WHERE pid IN (5,3,4) ORDER BY pid ASC;Will return records 3, 4 and 5 (in that order)
jbudge
@Felix Kling Hold on. I tried only with two pids.
kampit
@Felix Kling Hold Yes working fine.
kampit
`$pid = explode(",", $order['pid']); $ipid = implode(' OR pid=', $pid); $select = 'SELECT * FROM download WHERE pid='.$ipid.'';` can be done too
kampit
I stand correct. Seems that the type conversion is more powerful than I thought. Impressive.
Felix Kling