CARVIEW |
Select Language
HTTP/2 200
date: Tue, 29 Jul 2025 11:47:27 GMT
content-type: text/html; charset=utf-8
vary: X-PJAX, X-PJAX-Container, Turbo-Visit, Turbo-Frame, X-Requested-With,Accept-Encoding, Accept, X-Requested-With
x-robots-tag: none
etag: W/"b5f5cdf62a6acf3dcb48ee730bed18e3"
cache-control: max-age=0, private, must-revalidate
strict-transport-security: max-age=31536000; includeSubdomains; preload
x-frame-options: deny
x-content-type-options: nosniff
x-xss-protection: 0
referrer-policy: no-referrer-when-downgrade
content-security-policy: default-src 'none'; base-uri 'self'; child-src github.githubassets.com github.com/assets-cdn/worker/ github.com/assets/ gist.github.com/assets-cdn/worker/; connect-src 'self' uploads.github.com www.githubstatus.com collector.github.com raw.githubusercontent.com api.github.com github-cloud.s3.amazonaws.com github-production-repository-file-5c1aeb.s3.amazonaws.com github-production-upload-manifest-file-7fdce7.s3.amazonaws.com github-production-user-asset-6210df.s3.amazonaws.com *.rel.tunnels.api.visualstudio.com wss://*.rel.tunnels.api.visualstudio.com objects-origin.githubusercontent.com copilot-proxy.githubusercontent.com proxy.individual.githubcopilot.com proxy.business.githubcopilot.com proxy.enterprise.githubcopilot.com *.actions.githubusercontent.com wss://*.actions.githubusercontent.com productionresultssa0.blob.core.windows.net/ productionresultssa1.blob.core.windows.net/ productionresultssa2.blob.core.windows.net/ productionresultssa3.blob.core.windows.net/ productionresultssa4.blob.core.windows.net/ productionresultssa5.blob.core.windows.net/ productionresultssa6.blob.core.windows.net/ productionresultssa7.blob.core.windows.net/ productionresultssa8.blob.core.windows.net/ productionresultssa9.blob.core.windows.net/ productionresultssa10.blob.core.windows.net/ productionresultssa11.blob.core.windows.net/ productionresultssa12.blob.core.windows.net/ productionresultssa13.blob.core.windows.net/ productionresultssa14.blob.core.windows.net/ productionresultssa15.blob.core.windows.net/ productionresultssa16.blob.core.windows.net/ productionresultssa17.blob.core.windows.net/ productionresultssa18.blob.core.windows.net/ productionresultssa19.blob.core.windows.net/ github-production-repository-image-32fea6.s3.amazonaws.com github-production-release-asset-2e65be.s3.amazonaws.com insights.github.com wss://alive.github.com api.githubcopilot.com api.individual.githubcopilot.com api.business.githubcopilot.com api.enterprise.githubcopilot.com; font-src github.githubassets.com; form-action 'self' github.com gist.github.com copilot-workspace.githubnext.com objects-origin.githubusercontent.com; frame-ancestors 'none'; frame-src viewscreen.githubusercontent.com notebooks.githubusercontent.com; img-src 'self' data: blob: github.githubassets.com media.githubusercontent.com camo.githubusercontent.com identicons.github.com avatars.githubusercontent.com private-avatars.githubusercontent.com github-cloud.s3.amazonaws.com objects.githubusercontent.com release-assets.githubusercontent.com secured-user-images.githubusercontent.com/ user-images.githubusercontent.com/ private-user-images.githubusercontent.com opengraph.githubassets.com copilotprodattachments.blob.core.windows.net/github-production-copilot-attachments/ github-production-user-asset-6210df.s3.amazonaws.com customer-stories-feed.github.com spotlights-feed.github.com objects-origin.githubusercontent.com *.githubusercontent.com; manifest-src 'self'; media-src github.com user-images.githubusercontent.com/ secured-user-images.githubusercontent.com/ private-user-images.githubusercontent.com github-production-user-asset-6210df.s3.amazonaws.com gist.github.com; script-src github.githubassets.com; style-src 'unsafe-inline' github.githubassets.com; upgrade-insecure-requests; worker-src github.githubassets.com github.com/assets-cdn/worker/ github.com/assets/ gist.github.com/assets-cdn/worker/
server: github.com
content-encoding: gzip
accept-ranges: bytes
set-cookie: _gh_sess=NVPP42C%2Fo5ynLcqQh%2BCHIZEj%2BCingcR5E5PU%2F3tNJAgZ%2BRNskzlvM9gGVSx0O6wst7Zy2zi%2F7iXYPnEu%2BbsLzngqqHNplpstb0G1CvfwOQcCqQAmVuALsUXFiztZbobmD0Dx0u6bxajTnFYL0%2BG41AS%2BR5%2BlQQmTi58a4H0W7MAr38r0NhbdFPrY09J0fOMWIEoUW4eloGlBo59Vsu%2BDNtuVuB1llZw2cUPb7bDezhxEJ%2BFNeBaX%2BXAjb1riH%2FZbLBPJb5V2V361xIv0Sj40EA%3D%3D--YoPe0XOZEvi44OFk--SB1EI2wG2ltIpQP%2BsHm9tg%3D%3D; Path=/; HttpOnly; Secure; SameSite=Lax
set-cookie: _octo=GH1.1.16417210.1753789647; Path=/; Domain=github.com; Expires=Wed, 29 Jul 2026 11:47:27 GMT; Secure; SameSite=Lax
set-cookie: logged_in=no; Path=/; Domain=github.com; Expires=Wed, 29 Jul 2026 11:47:27 GMT; HttpOnly; Secure; SameSite=Lax
x-github-request-id: 9304:8019C:A08A3D:C019D7:6888B4CF
Publishing Efficient Joined Queries · numtel/meteor-mysql Wiki · GitHub
Skip to content
Navigation Menu
{{ message }}
-
Notifications
You must be signed in to change notification settings - Fork 40
Publishing Efficient Joined Queries
Ben Green edited this page Sep 15, 2015
·
8 revisions
Suppose that you were trying to publish the following parameterized query: (Example SQL data is listed at the end of this page)
SELECT
students.name AS student_name,
students.id AS student_id,
assignments.name,
assignments.value,
scores.score
FROM
scores
INNER JOIN assignments ON
(assignments.id = scores.assignment_id)
INNER JOIN students ON
(students.id = scores.student_id)
WHERE
assignments.class_id = ?;
The result set of this query will need to be refreshed when:
- An
assignments
row changes that matches theclass_id
given - Any
students
row included in the results changes (in case thename
changes) - Or any
scores
row changes that matches anassignments
row with the correctclass_id
In order to write triggers for this joined query, an extra supporting query to load all of the assignments
rows that match the selected class_id
.
The following code listing provides a complete Meteor.publish
function for this query:
ECMAScript 6 'template strings' are used in the following example to make writing SQL queries in Javascript code much easier. Read more about ES6 template strings or check out the
grigio:babel
package for using ES6 with Meteor...
Meteor.publish('myClassScores', function(classId) {
if(typeof classId !== 'number')
throw new Error('classId must be integer');
// Triggers require caches of columns that are joined on
var assignmentIds = [], studentIds = [];
// Prepare supporting query to main query
var classAssignments = liveDb.select(`
SELECT
id
FROM
assignments
WHERE
class_id = ${liveDb.db.escape(classId)}
`, [ {
table: 'assignments',
condition: function(row, newRow){
return row.class_id === classId ||
(newRow && newRow.class_id === classId);
}
} ]
);
// Update cache on new data
classAssignments.on('update', function(diff, results) {
assignmentIds = results.map(function(row) { return row.id });
});
// Subscription has been stopped, also stop supporting query
this.onStop(function() {
classAssignments.stop();
});
var classScores = liveDb.select(`
SELECT
students.name AS student_name,
students.id AS student_id,
assignments.name,
assignments.value,
scores.score
FROM
scores
INNER JOIN assignments ON
(assignments.id = scores.assignment_id)
INNER JOIN students ON
(students.id = scores.student_id)
WHERE
assignments.class_id = ${liveDb.db.escape(classId)};
`, [
{
table: 'assignments',
condition: function(row, newRow) {
// newRow only passed on UPDATE events
return row.class_id === classId ||
(newRow && newRow.class_id === classId)
}
},
{
table: 'students',
condition: function(row, newRow) {
// Check if the id of this row matches cache value set
return studentIds.indexOf(row.id) !== -1 ||
(newRow && studentIds.indexOf(newRow.id) !== -1)
}
},
{
table: 'scores',
condition: function(row, newRow) {
// Check if the assignment_id of this row matches cache value set
return assignmentIds.indexOf(row.assignment_id) !== -1 ||
(newRow && assignmentIds.indexOf(newRow.assignment_id) !== -1)
}
}
]);
classScores.on('update', function(diff, results) {
// Update student_id cache
studentIds = results.map(function(row) { return row.student_id });
});
return classScores;
});
CREATE TABLE `students` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
INSERT INTO `students` VALUES
(1 , 'John Doe'),
(2 , 'Larry Loe');
CREATE TABLE `assignments` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`class_id` int(11) NOT NULL,
`name` varchar(45) DEFAULT NULL,
`value` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;
INSERT INTO `assignments` VALUES
(1 , 1 , 'Homework' , 10),
(2 , 1 , 'Test' , 100),
(3 , 2 , 'Art Project' , 30),
(4 , 1 , 'HW 2' , 10),
(5 , 1 , 'HW 3' , 10);
CREATE TABLE `scores` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`assignment_id` int(11) NOT NULL,
`student_id` int(11) NOT NULL,
`score` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1;
INSERT INTO `scores` VALUES
(1 , 1 , 1 , 10),
(2 , 1 , 2 , 8),
(3 , 2 , 1 , 70),
(4 , 2 , 2 , 82),
(5 , 3 , 1 , 15),
(8 , 5 , 1 , 10);
You can’t perform that action at this time.