How to select Multiple Rows based on one Column - sql

So I have looked around the internet, and couldn't find anything that could be related to my issue.
This is part of my DB:
ID | English | Pun | SID | Writer |
=======================================================
1 | stuff | stuff | 1 | Full |
2 | stuff | stuff | 1 | Rec. |
3 | stuff | stuff | 2 | Full |
4 | stuff | stuff | 2 | Rec. |
Now how would I get all rows with SID being equal to 1.
Like this
ID | English | Pun | SID | Writer |
=======================================================
1 | stuff | stuff | 1 | Full |
2 | stuff | stuff | 1 | Rec. |
Or when I want to get all rows with SID being equal to 2.
ID | English | Pun | SID | Writer |
=======================================================
3 | stuff | stuff | 2 | Full |
4 | stuff | stuff | 2 | Rec. |
This is my current SQL Query using SQLite:
SELECT * FROM table_name WHERE SID = 1
And I only get the first row, how would I be able to get all of the rows?
Here is my PHP Code:
class GurDB extends SQLite3
{
function __construct()
{
$this->open('gurbani.db3');
}
}
$db = new GurDB();
$mode = $_GET["mode"];
if($mode == "2") {
$shabadnum = $_GET["shabadNo"];
$result = $db->query("SELECT * FROM table_name WHERE SID = $shabadnum");
$array = $result->fetchArray(SQLITE3_ASSOC);
print_r($array);
}

Fetch array only gives you one row... you want something like this:
while($row = $result->fetch_array())
{
$rows[] = $row;
}

Related

PowerBI / SQL Query to verify records

I am working on a PowerBI report that is grabbing information from SQL and I cannot find a way to solve my problem using PowerBI or how to write the required code. My first table, Certifications, includes a list of certifications and required trainings that must be obtained in order to have an active certification.
My second table, UserCertifications, includes a list of UserIDs, certifications, and the trainings associated with a certification.
How can I write a SQL code or PowerBI measure to tell if a user has all required trainings for a certification? ie, if UserID 1 has the A certification, how can I verify that they have the TrainingIDs of 1, 10, and 150 associated with it?
Certifications:
CertificationsTable
UserCertifications:
UserCertificationsTable
This is a DAX pattern to test if contains at least some values.
| Certifications |
|----------------|------------|
| Certification | TrainingID |
|----------------|------------|
| A | 1 |
| A | 10 |
| A | 150 |
| B | 7 |
| B | 9 |
| UserCertifications |
|--------------------|---------------|----------|
| UserID | Certification | Training |
|--------------------|---------------|----------|
| 1 | A | 1 |
| 1 | A | 10 |
| 1 | A | 300 |
| 2 | A | 150 |
| 2 | B | 9 |
| 2 | B | 90 |
| 3 | A | 7 |
| 4 | A | 1 |
| 4 | A | 10 |
| 4 | A | 150 |
| 4 | A | 1000 |
In the above scenario, DAX needs to find out if the mandatory trainings (Certifications[TrainingID]) by Certifications[Certification] is completed by
UserCertifications[UserID ]&&UserCertifications[Certifications] partition.
In the above scenario, DAX should only return true for UserCertifications[UserID ]=4 as it is the only User that completed at least all the mandatory trainings.
The way to achieve this is through the following measure
areAllMandatoryTrainingCompleted =
VAR _alreadyCompleted =
CONCATENATEX (
UserCertifications,
UserCertifications[Training],
"-",
UserCertifications[Training]
) // what is completed in the fact Table; the fourth argument is very important as it decides the sort order
VAR _0 =
MAX ( UserCertifications[Certification] )
VAR _supposedToComplete =
CONCATENATEX (
FILTER ( Certifications, Certifications[Certification] = _0 ),
Certifications[TrainingID],
"-",
Certifications[TrainingID]
) // what is comeleted in the training Table; the fourth argument is very important as it decides the sort order
VAR _isMandatoryTrainingCompleted =
CONTAINSSTRING ( _alreadyCompleted, _supposedToComplete ) // CONTAINSSTRING (<Within Text>,<Search Text>); return true false
RETURN
_isMandatoryTrainingCompleted

SELECT 1 ID and all belonging elements

I try to create a json select query which can give me back the result on next way.
1 row contains 1 main_message_id and belonging messages. (Like the bottom image.) The json format is not a requirement, if its work with other methods, it will be fine.
I store the data as like this:
+-----------------+---------+----------------+
| main_message_id | message | sub_message_id |
+-----------------+---------+----------------+
| 1 | test 1 | 1 |
| 1 | test 2 | 2 |
| 1 | test 3 | 3 |
| 2 | test 4 | 4 |
| 2 | test 5 | 5 |
| 3 | test 6 | 6 |
+-----------------+---------+----------------+
I would like to create a query, which give me back the data as like this:
+-----------------+-----------------------+--+
| main_message_id | message | |
+-----------------+-----------------------+--+
| 1 | {test1}{test2}{test3} | |
| 2 | {test4}{test5}{test6} | |
| 3 | {test7}{test8}{test9} | |
+-----------------+-----------------------+--+
You can use json_agg() for that:
select main_message_id, json_agg(message) as messages
from the_table
group by main_message_id;
Note that {test1}{test2}{test3} is invalid JSON, the above will return a valid JSON array e.g. ["test1", "test2", "test3"]
If you just want a comma separated list, use string_agg();
select main_message_id, string_ag(message, ', ') as messages
from the_table
group by main_message_id;

SQL Query (Display All 'x' Where 'x' Is Not In Table '2' for field 'y' and has 'z' flag)

I need to return all 'contacts' that do not appear in the 'delegate' table for 'event name' but do have flags in the 'contacts' table that can selected by the user for the search.
I know the query can be broken in to 2 parts.
Are they already attending this event (Does their email appear in 'delegates' table with delegates.event field matching 'event' on the user form)
WHERE (
d.Event <> [Forms]![usf_FindCampaignContacts]![FCC_EventName]
Do they match the criteria (Have they got the HR flag in 'contacts' table)
AND (c.[HR-DEL] = [Forms]![usf_FindCampaignContacts]![FCC_HRD] OR IsNull([Forms]![usf_FindCampaignContacts]![FCC_HRD]));
Based on the 2 things that the query is required to do I have written the following code...
SELECT
c.[First Name], c.[Last Name], c.Email, d.Event, c.Suppress, c.[HR-DEL]
FROM tbl_Contacts AS c LEFT JOIN tbl_Delegates AS d ON c.Email = d.Email
WHERE (
d.Event <> [Forms]![usf_FindCampaignContacts]![FCC_EventName]
And
c.Suppress = False
)
AND (c.[HR-DEL] = [Forms]![usf_FindCampaignContacts]![FCC_HRD] OR IsNull([Forms]![usf_FindCampaignContacts]![FCC_HRD]));
[FCC_HRD] refers to the user selected input on the form, I tried to use a <> to remove matching records but I feel this is where the compile error is so I changed these to and/or statements and this part now returns results with the matching flags (Success)
Other issue with attempting to do it this way is even if it worked it would remove anyone who was listed in the delegates/sponsor table. Which is why I added the <> statement for the Event as it only needs to remove them off the list for the named event. Again this works perfectly well (Success)
Final issue is the results are clearly being pulled from the 'delegates' table not the 'contacts' table as both parts above work but only display the results that match criteria in delegates table not from contacts.
Here is the query/table relationships
Here is the user form (This is not the final design)
Below are the 3 tables that are used in the query (2 direct, 1 linked)
Contacts (c)
+----+------------+---------------+-------------------------+--------+----------+
| ID | First Name | Last Name | Email | HR-DEL | Suppress |
+----+------------+---------------+-------------------------+--------+----------+
| 1 | A | Platt | a.platt#fake.com | TRUE | TRUE |
| 2 | D | Farr | d.farr#fake.com | TRUE | FALSE |
| 3 | Y | Helle | y.helle#fake.com | TRUE | FALSE |
| 4 | S | Oliphant | soliphant#fake.com | TRUE | FALSE |
| 5 | J | Bedell-Pearce | jbedell-pearce#fake.com | TRUE | FALSE |
| 6 | J | Walker | j.walker#fake.com | FALSE | FALSE |
| 7 | S | Rug | s.rug#fake.com | FALSE | FALSE |
| 8 | D | Brown | d.brown#fake.com | FALSE | FALSE |
| 9 | R | Cooper | r.cooper#fake.com | TRUE | FALSE |
| 10 | M | Morrall | m.morrall#fake.com | TRUE | FALSE |
+----+------------+---------------+-------------------------+--------+----------+
Delegates (d)
+----+-------------------------+-------+
| ID | Email | Event |
+----+-------------------------+-------+
| 1 | a.platt#fake.com | 2 |
| 2 | d.farr#fake.com | 1 |
| 3 | y.helle#fake.com | 4 |
| 4 | soliphant#fake.com | 3 |
| 6 | jbedell-pearce#fake.com | 2 |
+----+-------------------------+-------+
Events (not direct but used to check event name drop-down on user form vs event number in delegates)
+----+------------+
| ID | Event Name |
+----+------------+
| 1 | Test 1 |
| 2 | Test 2 |
| 3 | Test 3 |
| 4 | Test 4 |
+----+------------+
Based on form selection and this sample data I need to return the following:
All contacts who are flagged 'HR' TRUE, not suppressed or going to event named 'test 2' (Should be 5 - I always return the names of 'delegates' not going to the event only = 3)
Final results should be:
+----+------------+-----------+--------------------+--------+----------+
| ID | First Name | Last Name | Email | HR-DEL | Suppress |
+----+------------+-----------+--------------------+--------+----------+
| 2 | D | Farr | d.farr#fake.com | TRUE | FALSE |
| 3 | Y | Helle | y.helle#fake.com | TRUE | FALSE |
| 4 | S | Oliphant | soliphant#fake.com | TRUE | FALSE |
| 9 | R | Cooper | r.cooper#fake.com | TRUE | FALSE |
| 10 | M | Morrall | m.morrall#fake.com | TRUE | FALSE |
+----+------------+-----------+--------------------+--------+----------+
At the moment it appears to be pulling results from the wrong table (d not c). I attempted to change to OUTER join type but that returned with a FROM syntax error.
If I understand it correctly, basically you want to do this:
SELECT A.foo
FROM A
LEFT JOIN B
ON A.bar = B.bar
WHERE
<complex condition, partly involving B>
This cannot work. By including B in the global WHERE condition, you turn the LEFT JOIN into an INNER JOIN, and so you will only ever get records that match between A and B.
You can either move the filter on B into the JOIN condition:
SELECT A.foo
FROM A
LEFT JOIN B
ON (A.bar = B.bar)
AND (B.bamboozle = 42)
WHERE
A.columns = things
or LEFT JOIN a filtered subquery:
SELECT A.foo
FROM A
LEFT JOIN
(SELECT bar, columns FROM B
WHERE B.bamboozle = 42) AS B1
ON A.bar = B1.bar
WHERE
A.columns = things
So in your query, this is the bamboozle part you will need to move:
d.Event <> [Forms]![usf_FindCampaignContacts]![FCC_EventName]

Why isn't my Neo4j index applying?

I run the following queries:
CREATE INDEX ON :Role(id)
+-------------------+
| No data returned. |
+-------------------+
Indexes added: 1
CREATE (:Role {id:'abc'})
+-------------------+
| No data returned. |
+-------------------+
Nodes created: 1
Properties set: 1
Labels added: 1
And next, for some reason, the index is not used when I try to fetch the Role that I just created. Can you explain why?
neo4j-sh (?)$ PROFILE MATCH (role:Role {id:'abc'})
> RETURN role.id;
+---------+
| role.id |
+---------+
| "abc" |
+---------+
1 row
7 ms
Compiler CYPHER 2.2
Planner COST
Projection
|
+Filter
|
+NodeByLabelScan
+-----------------+---------------+------+--------+---------------+----------------------------+
| Operator | EstimatedRows | Rows | DbHits | Identifiers | Other |
+-----------------+---------------+------+--------+---------------+----------------------------+
| Projection | 1 | 1 | 1 | role, role.id | role.id |
| Filter | 1 | 1 | 5 | role | role.id == { AUTOSTRING0} |
| NodeByLabelScan | 6 | 5 | 6 | role | :Role |
+-----------------+---------------+------+--------+---------------+----------------------------+
Total database accesses: 12
You forgot to use the index.
Try this:
MATCH (role:Role)
USING INDEX role:Role(id)
WHERE role.id='abc'
RETURN role.id
Projection
|
+Expand(All)
|
+NodeIndexSeek
Total database accesses: 4

Shifting hierarchyid set

I have a table that contains a set of values and a hierarchyid column. Looks something like this:
+-----+-------------+-----------+
| ID | HierarchyID | Name | HierarchyID.ToString() for clarity
+-----+-------------+-----------+
| 1 | 0x58 | Testing | /1/
| 2 | 0x5AC0 | TChild1 | /1/1
| 3 | 0x5AD6 | TChild1.1 | /1/1/1
| 4 | 0x5ADA | TChild1.2 | /1/1/2/
| 5 | 0x68 | Example | /2/
| 6 | 0x6AC0 | EChild1 | /2/1
| ... | ... | ... |
+-----+-------------+-----------+
However, we are introducing a new data set of that aligns side by side with the current tree and I'll need to shift all the values in my current tree down a level so it should look something like this now.
+-----+-------------+-----------+
| ID | HierarchyID | Name | HierarchyID.ToString() for clarity
+-----+-------------+-----------+
| | 0x58 | OldData | /1/
| 1 | 0x5AC0 | Testing | /1/1/
| 2 | 0x5AC6 | TChild1 | /1/1/1
| 3 | 0x5AD6B0 | TChild1.1 | /1/1/1/1
| 4 | 0x5AD6D0 | TChild1.2 | /1/1/1/2/
| 5 | 0x5B40 | Example | /1/2/
| 6 | 0x5B56 | EChild1 | /1/2/1
| 6 | 0x68 | NewData | /2
| 6 | 0x6AC0 | NChild1 | /2/1
| ... | ... | ... |
+-----+-------------+-----------+
Is there an easy way to update all of my hierarchyid values to shift them down a level or do I have to update each row one by one without overlapping values on updates?
Just from looking up the documentation.
There is an easy way to move a subtree.
Working with hierarchyid Data
Under Moving Subtree there is an example for an Employee hierarchy.
You will have to adjust to your table structure.
CREATE PROCEDURE MoveOrg(#oldMgr nvarchar(256), #newMgr nvarchar(256) )
AS
BEGIN
DECLARE #nold hierarchyid, #nnew hierarchyid
SELECT #nold = OrgNode FROM HumanResources.EmployeeDemo WHERE LoginID = #oldMgr ;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION
SELECT #nnew = OrgNode FROM HumanResources.EmployeeDemo WHERE LoginID = #newMgr ;
SELECT #nnew = #nnew.GetDescendant(max(OrgNode), NULL)
FROM HumanResources.EmployeeDemo WHERE OrgNode.GetAncestor(1)=#nnew ;
UPDATE HumanResources.EmployeeDemo
SET OrgNode = OrgNode.GetReparentedValue(#nold, #nnew)
WHERE OrgNode.IsDescendantOf(#nold) = 1 ;
COMMIT TRANSACTION
END ;
GO