How to retrieve data from mysql db by passing an array - mysql

I have an dynamic array of id which is passed by frontend. I need to fetch data from mysql db where the tuples ids are match with the ids which i pass.
Example Id array: [6, 7, ...]
The number of items can be vary according to different requests.
SELECT expense_type, expense_category FROM expense_type WHERE expense_category_id=id1 OR expense_category_id=id2;
id1, id2 are the ids which comes from the frontend. (6,7,...)
There can be multiple ids which comes from the frontend.
could i please know is there a way to fetch data from one query in such situation.
Or else do i have to write multiple queries to execute?

You need to make query by using that multiple ids's array.
something like below
query = 'SELECT expense_type, expense_category FROM expense_type WHERE expense_category_id IN (`;
forEach(ids as id) {
query += id + ','
}
run query..

To select data based on an array of values you can use the IN-keyword. In your case it would look like this:
SELECT expense_type, expense_category
FROM expense_type
WHERE expense_category_id IN ('id1', 'id2');

you can easily use an IN.
also try to use Join. so the accuracy of the query will get increase.
SELECT expense_type, expense_category
FROM expense_type
WHERE expense_category_id IN ('id1', 'id2');

Related

JOIN on keys that don't have the same value

I am trying to do an INNER JOIN on two tables that have similar values, but not quite the same. One table has a fully qualified host name for its primary key, and the other the hosts short name, as well as the subdomain. It it safe to assume that the short name and the subdomain together are unique.
So I've tried:
SELECT table1.nisinfo.* FROM table1.nisinfo INNER JOIN table2.hosts ON (table1.nisinfo.shortname + '.' + table1.nisinfo.subdomainname + '.domain.com') = table2.hosts.fqhn WHERE table2.hosts.package = 'somepkg';
This doesn't return the results I expect, it returns the first result hundreds of times. I'd like to return distinct rows. It takes a long time to run as well.
What am I doing wrong? I was thinking of running a subquery to get the hostnames, but I don't know what the right path from here is.
Thank you!
You can use group by in your query so you can achieve the desired results you want
please see this two links
Group by with 2 distinct columns in SQL Server
http://www.sqlteam.com/article/how-to-use-group-by-with-distinct-aggregates-and-derived-tables
Try putting your results into a temp table and then view the table to make sure that the columns are as expected.
SELECT table1.nisinfo.*, table1.nisinfo.shortname + '.' + table1.nisinfo.subdomainname + '.domain.com' AS ColID
INTO #temp
FROM table1.nisinfo;
Select *
from #temp INNER JOIN table2.hosts ON ##temp.ColID = table2.hosts.fqhn
WHERE table2.hosts.package = 'somepkg'
;
Put a Group By clause at the end of the second statement
So in this case, I used a subquery to get the initial results, and then used a join.
SELECT table1.nisinfo.* FROM table1.nisinfo JOIN (SELECT distinct(fqhn) FROM table2.hosts WHERE package = 'bash') AS FQ ON ((SUBSTRING_INDEX(FQ.fqhn, '.', 1)) = table1.nisinfo.shortname);

Need to convert an array to Integer for a MySQL query in a Rails API

I have a piece of code which fetches the list of ids of users I follow.
#followed = current_user.followed_user_ids
It gives me a result like this [11,3,24,42]
I need to add these to NOT IN mysql query.
Currently, I am getting NOT IN ([11,3,24,42]) which is throwing an error. I need NOT IN (11,3,24,42)
This is a part of a find_by_sql statement, so using where.not is not possible for me in this point.
In rails 4:
#followed = current_user.followed_user_ids # #followed = [11,3,24,42]
#not_followed = User.where.not(id: #followed)
This should generate something like select * from users where id not in (11,3,24,42)
As you comment, you are using find_by_slq (and that is available in all rails versions). Then you could use the join method:
query = "select * from users where id not in (#{#followed.join(',')})"
This would raise mysql errors if #followed is blank, the resulting query would be
select * from users where id not in ()
To solve this whiout specifiying aditional if statements to your code, you can use:
query = "select * from users where id not in (0#{#followed.join(',')})"
Your normal queries would be like:
select * from users where id not in (01,2,3,4)
but if the array is blank then would result in
select * from users where id not in (0)
which is a still valid sql statement and is delivering no results (which might be the expected situation in your scenario).
you can do something like:
#followed = [11,3,24,42]
User.where('id not in (?)', #followed)

MySql dynamic column name

[major edit to make things clear]
I want to write a query that returns a dynamic column name like this:
SELECT
f2 AS
(
SELECT column_name
FROM column_names_tbl
WHERE column_name = "experience"
limit 0,1
)
FROM some_table
so that would output the same as this:
SELECT
f2 AS experience
FROM some_table
This is no correct SQL syntax, even because the two queries (the selected field and it's alias) are both subqueries and unrelated to each other. So, there's also no possibility for mysql to distinguish what name you want to connect to what value, even if the syntax was correct...
You already use a more or less normalized relational table, so I suggest the following solution:
you select the revision ID and name in a separate query; store them in PHP and use them for whatever you want
next, you evaluate the following query into a separated result set: SELECT ps.keyname, psv.keyvalue FROM page_setting_values AS psv INNER JOIN page_settings AS ps ON ps.id = psv.setting_id WHERE psv.page_revision_id = :revision with :revision representing your revision id
you may now assemble an associated array from that result set:
$settings = [];
$result = $db->executeQuery('...')->fetchAll();
foreach($result as $setting)
{
$settings[$setting['keyname']] = $setting['keyvalue'];
}
Hope that helps ;)

Using Django Count() with conditional lookup types

So I'm trying to aggregate exam data, and because the database lives on another server I'm trying to reduce this to as few database calls as possible.
I have this model (whose corresponding table is in a mySQL database if that matters):
class Exam(models.Model):
submitted = models.BooleanField(default=False)
score = models.DecimalField(default=Decimal(0))
And this query:
>>> exam_models.Exam.objects\
... .using("exam_datebase")\
... .aggregate(average=Avg("score"),
... total=Count("submitted"))
{'average': 22.251082, 'total': 231}
What I'm looking for is a way to also retrieve the number of passed exams, something along the lines of:
>>> exam_models.Exam.objects\
... .using("exam_datebase")\
... .aggregate(average=Avg("score"),
... total=Count("submitted"))
... passed=Count("score__gte=80"))
{'average': 22.251082, 'total': 231, 'passed': 42}
I know I can just send another query using .filter(score__gte=80).count(), but I was really hoping to get both the total count and the passing count on the same aggregate. Any ideas?
You are either going to need two queries, or do the aggregation manually.
To see why, let's consider the underlying SQL that Django generates and uses to query the database.
Exam.objects.aggregate(average=Avg("score"), total=Count("submitted"))
roughly translates to
SELECT AVG(score), COUNT(submitted)
FROM exam
The "Count" part of the aggregate is applying to the SELECT clause in the underlying sql query. But if we want to include only scores greater than some value, the SQL query would need to look something like this:
SELECT AVG(score), COUNT(submitted)
FROM exam
WHERE score > 80
Filtering Exams with a particular "score" is applies to the WHERE or HAVING clause of the underlying SQL statement.
Unfortunately, there is not really a way to combine these two things. So, you are stuck doing two queries.
Having said all that, if you REALLY want to do a single query, one option is to just do the aggregation in your python code:
exams = Exam.objects.all()
total_score = 0
total_submitted = 0
passed = 0
for exam in exams:
total_score += exam.score
if exam.submitted:
total_submitted += 1
if exam.score >= 80:
passed += 1
exam_aggregates = {
'average': total_score / len(exams),
'submitted': total_submitted,
'passed': passed,
}

Store procedure select all fields from One table using join

I am very frustrated from linq to sql when dealing with many to many relationship with the skip extension. It doesn't allow me to use joinned queries. Not sure it is the case for SQL server 2005 but I am currently using SQL Server 2000.
Now I consider to write a store procedure to fetch a table that is matched by two tables e.g. Album_Photo (Album->Album_Photo<-Photo) and Photo table and only want the Photos data so I match the Album's ID with Album_Photo and use that ID to match the photo. In the store procedure I am just fetch all the joinned data. After that in the linq to sql, I create a new Album object.
e.g.
var albums = (from r in result
where (modifier_id == r.ModifierID || user_id == r.UserID)
select new Album() {
Name = r.Name,
UserID = r.UserID,
ModifierID = r.ModifierID,
ID = r.ID,
DateCreated = r.DateCreated,
Description = r.Description,
Filename = r.Filename
}).AsQueryable();
I used the AsQueryable to get the result as a IQueryable rather than IEnumerable. Later I want to do something with the collection, it gives me this error:
System.InvalidOperationException: The query results cannot be enumerated more than once.
It sounds like you have a situation where the query has already executed by the time you are want to filter it later in your code.
Can you do something like...
var albums = (blah blah blah).AsQueryable().Where(filterClause) when you have enough info to process
what happens if you try albums.where(filter) later on in the code? Is this what you are trying?