I wanna to make limit check. Primary - check if name already in last 3 lines. How to make?
$connect = db_connect();
$query = "SELECT * FROM `lastest` WHERE `name` LIKE '" .$name. "'";
$result = db_query($query, $connect);
if ($result) {
die('Already in db.'); }
Check is_exists column, this what i can suggest to you:
is_exists = 1 => Name exists
is_exists = 0 => Name doesn't exists
SELECT count(*) as is_exists,GROUP_CONCAT(`fname`) as a
FROM test.users
HAVING a LIKE "% YOUR_NAME %"
ORDER BY `fname` DESC
LIMIT 3 ;
Try it and let me know if it was help you
Don't hesitate ask any questions
Good luck
If your column id is "id" :
Googling "sql get last rows" (without quotes) leads to this page :
http://www.w3schools.com/sql/sql_func_last.asp
Pick up your db, and customize the request to get the 3 last lines. Then write a request querying a sub-request (this one who gets the 3 last lines) with your where statment...
So, assuming that your primary key is "id" :
SELECT COUNT(*)
FROM
(SELECT id, name
FROM lastest
ORDER BY id DESC
LIMIT 3) sub_lastest
WHERE `name` LIKE [name];
Related
This is a simple question.
Background
I'm supposed to have max of 400 rows in some table, based on timestamp field, so old ones will be removed automatically. For here, let's say it's 3 instead.
The table has various fields, but the timestamp is what's important here.
The problem
Even though I've succeeded (looked here), for some reason it got me to a max of an additional item, so I just adjusted it accordingly. This means that instead of 3, I got 4 items.
private const val MAX_ITEMS = 3
private val TIMESTAMP_FIELD = "timestamp"
private val DELETE_FROM_CALL_LOG_TILL_TRIGGER =
String.format(
"CREATE TRIGGER %1\$s INSERT ON %2\$s
WHEN (select count(*) from %2\$s)>%3\$s
BEGIN
DELETE FROM %2\$s WHERE %2\$s._id IN " +
"(SELECT %2\$s._id FROM %2\$s ORDER BY %2\$s.$TIMESTAMP_FIELD DESC LIMIT %3\$d, -1);
END;"
, "delete_till_reached_max", TABLE_NAME, MAX_ITEMS - 1)
What I've tried
I tried :
Change the condition to just being insertion (meaning without the WHEN part)
Change LIMIT %3\$d, -1 to LIMIT -1 OFFSET %3\$d . Also tried a different number than "-1" (tried 0, because I thought it's extra).
The questions
How come I had to use MAX_ITEMS - 1 instead of just MAX_ITEMS ? Why does it leave me with 4items instead of 3 ?
Does it matter if I have WHEN there? Is it better?
You have omitted the BEFORE | AFTER clause, so it's BEFORE by default. This means you are counting the rows before the insert, not after it.
This depends. At first, when the table has not reached the limit yet, the quick count lookup may save you some time, as you avoid the more complicated delete. But as soon as the table is full, you'll have to delete anyway, so counting is just additional work to do.
This should work:
private const val MAX_ITEMS = 3
private val TIMESTAMP_FIELD = "timestamp"
private val DELETE_FROM_CALL_LOG_TILL_TRIGGER =
String.format(
"CREATE TRIGGER %1\$s AFTER INSERT ON %2\$s
FOR EACH ROW
BEGIN
DELETE FROM %2\$s WHERE _id =
(SELECT _id FROM %2\$s ORDER BY %4\$s DESC LIMIT 1 OFFSET %3\$s);
END;"
, "delete_till_reached_max", TABLE_NAME, MAX_ITEMS, TIMESTAMP_FIELD)
Once there are 400 rows in the table, you can just as well call the trigger something like trg_keep_rowcount_constant and remove GROUP BY null HAVING COUNT(*) > %3\$s from the code.
Demo: https://dbfiddle.uk/?rdbms=sqlite_3.27&fiddle=ea3867e20e85927a2de047908771f4f1
Edit: (Explanation added)
I have a table that stores some data, it has the structure indicated below.
id tparti_id orde desc
1 1 10 One thing
2 1 20 Another thing
3 1 30 Last task of the month
4 2 10 First of second month
5 2 20 Second and last of second month
6 3 10 First of third month
The orde field it's the the sequence of rows with the same tparti_id, this value it's used on our app to sort the contents given tparti_id, the user can reorder it changing the values in order.
The values stored came from a text file and are parsed by a CakePHP app.
When a new row it's inserted the next value in the sequence of orde is calculated by searching the current value in orde and adding 10 given an id, if no orde is found returns 10
public function nextOrden($tpid){
$sql = "select orde from tdpies where tparti_id =".$tpid." order by orde desc limit 1;";
$r = $this->query($sql,$cachequeries = false);
if ($r){
$res = $r[0][0]['orde'] + 10;
} else {
$res = 10;
}
return $res;
}
It's working ok when inserting few records, but when inserting thousands of records it's time consuming.
How can improve performance:
Using a trigger when a new record it's created?
Using a new sequence with some trickery inside?
Thanks
You seem to have an auto-incremented id so you could calculated orde when you query table rather tha when you create it:
select p.*, 10 * (row_number() over (partition by tparti_id order by id)) as orde
from tdpies p;
If you want to handle this on insert, then add an index on tdpies(tparti_id, orde). Inside the trigger, you'll have something like:
new.orde := (select coalesce(max(orde), 0) + 10
from tdpies p
where p.tparti_id = new.tparti_id
);
It can (and should) be done in SQL in instead of in PHP
$sql = "
select coalesce(max(orde), 0) + 10 as new_id
from tdpies
where tparti_id = $tpid
"
If max(orde) returns null when there is no matching tparti_id the coalesce function returns 0.
Notice that it is not necessary to concatenate $tpid as it will be evaluated inside a double quoted string.
It is better to do the insert in the same query
insert into tdpies (
id, tparti_id, orde, description
)
select
1, $tpid,
coalesce(max(orde), 0) + 10,
'something about months'
from tdpies
where tparti_id = $tpid
You need an unique constraint (tparti_id, orde) in order to keep the table integrity.
I have been trying to get the grasps of SQL, recently, and I was wondering if you could explain how you could use a WHERE/AND OR in a COUNT() to return the number of rows with a certain criteria...
Or am I looking into the wrong function? Any helpful comments are welcome
EDIT: Heres what I'm working with, I have a simple SELECT WHERE query to print out a profileName and profileIcon. I am using this as a test to see if COUNT works for what I want... I then want to run a COUNT to see how many ROWs are within the criteria.
$query = $con->query("SELECT * FROM user_settings WHERE Username='" . $_SESSION['user'] . "'");
while($row = $query->fetch_array()) {
echo '<tr><th>Current Icon:</th><td><img src="' . $row['ProfileIcon'] . '" /></td></tr>';
echo '<tr><th>Current Name:</th><td>' . $row['ProfileName'] . '</td></tr>';
}
$query = $con->query("SELECT SUM(CASE WHEN Username='" . $_SESSION['user'] ."' THEN 1 ELSE 0 END) FROM user_settings");
var_dump($query);
The var_dump produces: object(mysqli_result)#3 (0) { }
For a "conditional" COUNT, you can use a CASE expression and SUM, e.g.
SUM(CASE WHEN ColumnA = 'Bob' THEN 1 ELSE 0 END)
will count the number of rows where ColumnA is Bob, but will include all rows (whether they have Bob or not) in the result set.
I'd recommend that you read through the documentation for COUNT. It includes examples with fairly detailed explainations.
An example:
SELECT COUNT(*) FROM pet;
this would count all rows found in the pet table. You can append a WHERE-statement after this to include a certain criteria.
Something like this:
select x, count(*)
from y
where x = ?
group by x
having count(*) > ?
order by x
The having clause is optional.
God day.
I use MsSQl Server 2008;
Code:
$entersql="SELECT name
FROM (
SELECT name FROM
Hist_answer
WHERE id_city='$id_city' AND id_firm='$id_firm' AND id_service='$id_service'
) x
GROUP BY name
";
$enterres = sqlsrv_query($conn, $entersql, $params, $options);
while($i = sqlsrv_fetch_array($enterres, SQLSRV_FETCH_ASSOC))
{
if($inputby=='id_hist_answer'&&$typeby=='DESC'){$a--;}else{$a++;}
$name=($i['name']!='')? $i['name']:'0';
$sql11="SELECT
ha.unit as ha_unit,
ha.id_producer_goods as ha_id_producer_goods
FROM Hist_answer ha
WHERE ha.id_city='$id_city' AND ha.id_firm='$id_firm' AND ha.id_service='$id_service' AND ha.name='$name'";
$params = array();
$options = array( "Scrollable" => SQLSRV_CURSOR_KEYSET );
$res11 = sqlsrv_query($conn, $sql11,$params,$options);
$row_count_ha = sqlsrv_num_rows($res11);
}
In this code i do:
1) i selected all unique name (group by name);
2) in second sql($sql11) i do find count rows for each name.
Tell me please how do sql when i can find all unique name (group by name) and count rows for each unique name ?
You can get unique names and their counts in a single statement:
SELECT name, count(name) AS records
FROM Hist_answer
WHERE id_city='$id_city'
AND id_firm='$id_firm'
AND id_service='$id_service'
GROUP BY name
SELECT colname, count(colname) AS UniqueRecord_Count
FROM ascouser
GROUP BY colname
You can put your column name on which you wanna get count ,may be put Where clause for filtering records as you said.
This is the SQL query displayed by codeigniter:
SELECT * FROM (status_updates) JOIN friend_connections ON ((
status_updates.userid=friend_connections.userid) OR
(status_updates.userid=friend_connections.friend_id)) WHERE
status_updates.enabled = "1" AND friend_connections.enabled = "1"
ORDER BY status_updates.date desc, status_updates.time desc LIMIT 20
The Codeigniter commands i used were:
$this->db->from('status_updates');
$this->db->order_by("status_updates.date", "desc");
$this->db->order_by("status_updates.time", "desc");
$this->db->limit(20);
$this->db->join('status_updates', '((status_updates.userid=friend_connections.userid) OR (status_updates.userid=friend_connections.friend_id))');
What i'm trying to do is select everything in two tables, status_updates and friend_connections. status_updates has the one column userid which i want to match with either userid or friend_id from friend_connections. Can someone tell me how i can do this please?
Also i noticed that codeigniter removes the two opening parentheses after the ON command in the above sql query.
Copy of your own answer in order to remove this from the unanswered stack:
$sql = "SELECT * FROM (status_updates) JOIN friend_connections ON ((status_updates.userid=friend_connections.userid) OR (status_updates.userid=friend_connections.friend_id)) WHERE status_updates.enabled = "1" AND friend_connections.enabled = "1" ORDER BY status_updates.date desc, status_updates.time desc LIMIT 20";
$status = $this->db->query($sql);
Please don't upvote. It's not my answer.