// create a device
IrrlichtDevice *device =
createDevice( video::EDT_SOFTWARE, dimension2d<u32>(640, 480), 16, false, false, false, 0);
// Get a pointer to the VideoDriver, the SceneManager and the graphical user interface environment
IVideoDriver* driver = device->getVideoDriver();
ISceneManager* smgr = device->getSceneManager();
IGUIEnvironment* guienv = device->getGUIEnvironment();
// set the caption of windows
device->setWindowCaption(L"Hello World! - Irrlicht Engine Demo");
// add label
guienv->addStaticText(L"Hello World! This is the Irrlicht Software renderer!",
rect<s32>(10,10,260,22), true);
// add a logo
guienv->addImage(
driver->getTexture("../../media/irrlichtlogoalpha2.tga"),
core::position2d<s32>(10,20));
// skin and font
IGUISkin* skin = env->getSkin();
IGUIFont* font = env->getFont("../../media/fonthaettenschweiler.bmp");
if (font)
skin->setFont(font);
skin->setFont(env->getBuiltInFont(), EGDF_TOOLTIP);
// add button, you set it by your self
env->addButton(rect<s32>(10,240,110,240 + 32), 0, GUI_ID_QUIT_BUTTON,
L"Quit", L"Exits Program");
// add scrollbar
IGUIScrollBar* scrollbar = env->addScrollBar(true,
rect<s32>(150, 45, 350, 60), 0, GUI_ID_TRANSPARENCY_SCROLL_BAR);
scrollbar->setMax(255);
scrollbar->setPos(255);
setSkinTransparency( scrollbar->getPos(), env->getSkin());
// set scrollbar position to alpha value of an arbitrary element
scrollbar->setPos(env->getSkin()->getColor(EGDC_WINDOW).getAlpha());
// add listbox
IGUIListBox * listbox = env->addListBox(rect<s32>(50, 140, 250, 210));
// add editbox
env->addEditBox(L"Editable Text", rect<s32>(350, 80, 550, 100));
// Notes: more interface functions, go for the sample 5: user interfaces
// add file to archieve
device->getFileSystem()->addFileArchive("../../media/map-20kdm2.pk3");
// get mesh, sometimes the .bsp file
IAnimatedMesh* mesh = smgr->getMesh("../../media/sydney.md2");
// hill mesh
mesh = smgr->addHillPlaneMesh( "myHill",
core::dimension2d<f32>(20,20),
core::dimension2d<u32>(40,40), 0, 0,
core::dimension2d<f32>(0,0),
core::dimension2d<f32>(10,10));
// add node
// IAnimatedMeshSceneNode: Scene node capable of displaying an animated mesh and its shadow
IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh );
if (node) {
node->setPosition(core::vector3df(0,0,30));
node -> setMaterialFlag(EMF_LIGHTING, false);
node -> setMD2Animation(scene::EMAT_STAND);
node->setMaterialTexture( 0, driver->getTexture("../../media/sydney.bmp") );
}
// normal scene node: addOctreeSceneNode is for rendering using a octree to the scene graph.
scene::ISceneNode* node = 0;
if (mesh) {
node = smgr->addOctreeSceneNode(mesh->getMesh(0), 0, -1, 1024);
}
if (node) {
node->setPosition(core::vector3df(-1300,-144,-1249));
}
// sphere, 0.2 is its radius
scene::ISceneNode *sphereNode = smgr->addSphereSceneNode(0.2);
// cube
scene::ISceneNode *cubeNode=smgr->addCubeSceneNode(100.0f);
// cylinder
const IGeometryCreator* igCreator = smgr->getGeometryCreator();
IMesh* cylinder = igCreator->createCylinderMesh(1.0f, 5.0f, 30, video::SColor(255, 255, 255, 255), false);
scene::IMeshSceneNode* cylinderNode = smgr->addMeshSceneNode(cylinder);
// water surface node
node = smgr->addWaterSurfaceSceneNode(mesh->getMesh(0), 3.0f, 300.0f, 30.0f);
// light node
node = smgr->addLightSceneNode(0, core::vector3df(0,0,0),
video::SColorf(1.0f, 0.6f, 0.7f, 1.0f), 800.0f);
// terrain node
scene::ITerrainSceneNode* terrain = smgr->addTerrainSceneNode(
"../../media/terrain-heightmap.bmp",
0, // parent node
-1, // node id
core::vector3df(0.f, 0.f, 0.f), // position
core::vector3df(0.f, 0.f, 0.f), // rotation
core::vector3df(40.f, 4.4f, 40.f), // scale
video::SColor ( 255, 255, 255, 255 ), // vertexColor
5, // maxLOD
scene::ETPS_17, // patchSize
4 // smoothFactor
);
// skybox node
scene::ISceneNode* skybox=smgr->addSkyBoxSceneNode(
driver->getTexture("../../media/irrlicht2_up.jpg"),
driver->getTexture("../../media/irrlicht2_dn.jpg"),
driver->getTexture("../../media/irrlicht2_lf.jpg"),
driver->getTexture("../../media/irrlicht2_rt.jpg"),
driver->getTexture("../../media/irrlicht2_ft.jpg"),
driver->getTexture("../../media/irrlicht2_bk.jpg"));
// skydome node
scene::ISceneNode* skydome=smgr->addSkyDomeSceneNode(driver->getTexture("../../media/skydome.jpg"),16,8,0.95f,2.0f);
// billing board
scene::IBillboardSceneNode * bill = smgr->addBillboardSceneNode();
// Add an animator to the scence node
// rotate it
scene::ISceneNodeAnimator* anim =
smgr->createRotationAnimator(core::vector3df(0.8f, 0, 0.8f));
// flying circle
scene::ISceneNodeAnimator* anim =
smgr->createFlyCircleAnimator(core::vector3df(0,0,30), 20.0f);
// flying straight between two points
scene::ISceneNodeAnimator* anim =
smgr->createFlyStraightAnimator(core::vector3df(100, 0, 60),
core::vector3df(-100, 0, 60), 3500, true);
// collision
scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(
selector, camera, core::vector3df(30, 50, 30),
core::vector3df(0, -10, 0), core::vector3df(0, 30, 0));
if (anim) {
myNode->addAnimator(anim);
anim->drop();
anim = 0;
}
// when it's done, drop the node
myNode->drop();
myNode=0;
// draw 2D image, images is the image you load it from the computer
driver->draw2DImage(images, core::position2d<s32>(50,50),
core::rect<s32>(0,0,342,224), 0,
video::SColor(255,255,255,255), true);
// add triangle selector
scene::ITriangleSelector* selector = 0;
if (node)
{
node->setPosition(core::vector3df(-1350, -130, -1400));
selector = smgr->createOctreeTriangleSelector(
node->getMesh(), node, 128);
node->setTriangleSelector(selector);
}
// terrain triangle selector
scene::ITriangleSelector* selector = smgr->createTerrainTriangleSelector(terrain, 0);
// render to texture
ITexture* rt = driver->addRenderTargetTexture(core::dimension2d<u32>(256,256), "RTT1");
driver->setRenderTarget(rt, true, true, video::SColor(0,0,0,255));
// add a camera
smgr -> addCameraSceneNode(0, vector3df(0, 30, -40), vector3df(0, 5, 0))
// appropriate for first person shooters (FPS)
smgr->addCameraSceneNodeFPS();
// mouse cursor not visible
device->getCursorControl()->setVisible(false);
// draw everything
while(device->run()) {
driver -> beginScene(true, true, SColor(255, 100, 101, 140));
smgr -> drawAll();
guienv -> drawAll();
driver -> endScene();
}
device -> drop();
Maybe some beginner will be confused by some files used in Irrlicht, here we talked about pak, bsp file.
pak file:.pak file is a special compress file format, developed by Quake Game Company. It compresses multiple files, there are some differences between it and other compress file formats:
This tutorials are based on the irrlicht tutorial, show how to draw images, keycolor based sprites, transparent rectangles, and different fonts. You have to read the previous tutorials, because the tutorials will skips the knowledgement that we have already talked about before.
All 2d graphics in this example are put together into one texture, 2ddemo.png. Because we want to draw colorkey based sprites, we need to load this texture and tell the engine, which part of it should be transparent based on a colorkey.
You just ask for the color in this position, that’s it.
video::ITexture* images = driver->getTexture("../../media/2ddemo.png");
driver->makeColorKeyTexture(images, core::position2d<s32>(0,0));
Load two fonts
gui::IGUIFont* font = device->getGUIEnvironment()->getBuiltInFont();
gui::IGUIFont* font2 =
device->getGUIEnvironment()->getFont("../../media/fonthaettenschweiler.bmp");
core::rect<s32> imp1(349,15,385,78);
core::rect<s32> imp2(387,15,423,78);
Prepare a nicely filtering 2d render mode for special cases.
driver->getMaterial2D().TextureLayer[0].BilinearFilter=true;
driver->getMaterial2D().AntiAliasing=video::EAAM_FULL_BASIC;
This case only use 2d without any 3d
while(device->run() && driver)
{
if (device->isWindowActive())
{
u32 time = device->getTimer()->getTime();
driver->beginScene(true, true, video::SColor(255,120,102,136));
draw 3 sprites
// draw fire & dragons background world
driver->draw2DImage(images, core::position2d<s32>(50,50),
core::rect<s32>(0,0,342,224), 0,
video::SColor(255,255,255,255), true);
// draw flying imp
driver->draw2DImage(images, core::position2d<s32>(164,125),
(time/500 % 2) ? imp1 : imp2, 0,
video::SColor(255,255,255,255), true);
// draw second flying imp with colorcylce
driver->draw2DImage(images, core::position2d<s32>(270,105),
(time/500 % 2) ? imp1 : imp2, 0,
video::SColor(255,(time) % 255,255,255), true);
Draw some texts
if (font)
font->draw(L"This demo shows that Irrlicht is also capable of drawing 2D graphics.",
core::rect<s32>(130,10,300,50),
video::SColor(255,255,255,255));
if (font2)
font2->draw(L"Also mixing with 3d graphics is possible.",
core::rect<s32>(130,20,300,60),
video::SColor(255,time % 255,time % 255,255));
Draw the logo
driver->enableMaterial2D();
driver->draw2DImage(images, core::rect<s32>(10,10,108,48),
core::rect<s32>(354,87,442,118));
driver->enableMaterial2D(false);
Finally draw a half-transparent rect under the mouse cursor.
core::position2d<s32> m = device->getCursorControl()->getPosition();
driver->draw2DRectangle(video::SColor(100,255,255,255),
core::rect<s32>(m.X-20, m.Y-20, m.X+20, m.Y+20));
driver->endScene();
You can get the complete codes from Github
This tutorials are based on the irrlicht tutorial, show how to create and use windows, buttons, scroll bars, static texts, and list boxes.. You have to read the previous tutorials, because the tutorials will skips the knowledgement that we have already talked about before.
Declare a structure to hold some context for the event receiver and some values that we’ll use to identify individual GUI controls.
struct SAppContext
{
IrrlichtDevice *device;
s32 counter;
IGUIListBox* listbox;
};
enum
{
GUI_ID_QUIT_BUTTON = 101,
GUI_ID_NEW_WINDOW_BUTTON,
GUI_ID_FILE_OPEN_BUTTON,
GUI_ID_TRANSPARENCY_SCROLL_BAR
};
Change the transparency of the windows when you drag the scrollbar
void setSkinTransparency(s32 alpha, irr::gui::IGUISkin * skin)
{
for (s32 i=0; i<irr::gui::EGDC_COUNT ; ++i)
{
video::SColor col = skin->getColor((EGUI_DEFAULT_COLOR)i);
col.setAlpha(alpha);
skin->setColor((EGUI_DEFAULT_COLOR)i, col);
}
}
In this example, We only react to gui events, and if it’s such an event, we get the id of the caller (the gui element which caused the event) and get the pointer to the gui environment.
class MyEventReceiver : public IEventReceiver
{
public:
MyEventReceiver(SAppContext & context) : Context(context) { }
//SEvents hold information about an event
virtual bool onEvent(const SEvent& event) {
// We only react to gui events
if (event.EventType == EET_GUI_EVENT) {
s32 id = event.GUIEvent.Caller->getID();
IGUIEnvironment* env = Context.device->getGUIEnvironment();
switch(event.GUIEvent.EventType) {
/* GUI_ID_TRANSPARENCY_SCROLL_BAR to change the transparency of the skins, as long as we get the scroll value as the alpha value */
case EGET_SCROLL_BAR_CHANGED:
if (id == GUI_ID_TRANSPARENCY_SCROLL_BAR)
{
s32 pos = ((IGUIScrollBar*)event.GUIEvent.Caller)->getPos();
setSkinTransparency(pos, env->getSkin());
}
break;
// if it is a button
case EGET_BUTTON_CLICKED:
switch(id) {
case GUI_ID_QUIT_BUTTON:
Context.device->closeDevice();
return true;
case GUI_ID_NEW_WINDOW_BUTTON:
{
// add the text to the list box
Context.listbox->addItem(L"Window created");
Context.counter += 30;
if (Context.counter > 200)
Context.counter = 0;
// create a new window with name "test window"
IGUIWindow* window = env->addWindow(
rect<s32>(100 + Context.counter, 100 + Context.counter, 300 + Context.counter, 200 + Context.counter),
false, // modal?
L"Test window");
env->addStaticText(L"Please close me",
rect<s32>(35,35,140,50),
true, // border?
false, // wordwrap?
window);
}
return true;
case GUI_ID_FILE_OPEN_BUTTON:
Context.listbox->addItem(L"File open");
// file open dialog
env->addFileOpenDialog(L"Please choose a file.", true, 0, -1, true);
return true;
default:
return false;
}
break;
case EGET_FILE_SELECTED:
{
IGUIFileOpenDialog* dialog =
(IGUIFileOpenDialog*)event.GUIEvent.Caller;
Context.listbox->addItem(dialog->getFileName());
}
break;
default:
break;
}
}
return false;
}
private:
SAppContext & Context;
};
Then it’s the main part, just like the pevious example. And add the GUI environment pointer.
IGUIEnvironment* env = device->getGUIEnvironment();
Load Skin and font
IGUISkin* skin = env->getSkin();
IGUIFont* font = env->getFont("../../media/fonthaettenschweiler.bmp");
if (font)
skin->setFont(font);
skin->setFont(env->getBuiltInFont(), EGDF_TOOLTIP);
Add buttons
env->addButton(rect<s32>(10,240,110,240 + 32), 0, GUI_ID_QUIT_BUTTON,
L"Quit", L"Exits Program");
env->addButton(rect<s32>(10,280,110,280 + 32), 0, GUI_ID_NEW_WINDOW_BUTTON,
L"New Window", L"Launches a new Window");
env->addButton(rect<s32>(10,320,110,320 + 32), 0, GUI_ID_FILE_OPEN_BUTTON,
L"File Open", L"Opens a file");
Add scrollbar
env->addStaticText(L"Transparent Control:", rect<s32>(150,20,350,40), true);
IGUIScrollBar* scrollbar = env->addScrollBar(true,
rect<s32>(150, 45, 350, 60), 0, GUI_ID_TRANSPARENCY_SCROLL_BAR);
scrollbar->setMax(255);
scrollbar->setPos(255);
setSkinTransparency( scrollbar->getPos(), env->getSkin());
// set scrollbar position to alpha value of an arbitrary element
scrollbar->setPos(env->getSkin()->getColor(EGDC_WINDOW).getAlpha());
Add listbox and editbox
env->addStaticText(L"Logging ListBox:", rect<s32>(50,110,250,130), true);
IGUIListBox * listbox = env->addListBox(rect<s32>(50, 140, 250, 210));
env->addEditBox(L"Editable Text", rect<s32>(350, 80, 550, 100));
// Store the appropriate data in a context structure.
SAppContext context;
context.device = device;
context.counter = 0;
context.listbox = listbox;
// Then create the event receiver, giving it that context structure.
MyEventReceiver receiver(context);
// And tell the device to use our custom event receiver.
device->setEventReceiver(&receiver);
// create a nice Irrlicht Engine logo in the top left corner.
env->addImage(driver->getTexture("../../media/irrlichtlogo2.png"),
position2d<int>(10,10));
Done, Draw everything
You can get the complete codes from Github
Hello World!
What is the coder’s worst nightmare?
Code works perfectly after the first try. The starts are not even aligned today.
Favorite coffee shop is closed.
Client from hell.
Hey, I have an awesome idea that can change the world, you can code it for me, and I’ll give you 30% of the company.
This is the computer genius I told you about.
Note: It is from Quora.
This tutorials are based on the irrlicht tutorial, show how manual movement of nodes using the keyboard. You have to read the previous tutorials, because the tutorials will skips the knowledgement that we have already talked about before.
we need an object which is derived from the irr::IEventReceiver object. There is only one method to override: irr::IEventReceiver::OnEvent(). This method will be called by the engine once when an event happens. What we really want to know is whether a key is being held down, and so we will remember the current state of each key.
class MyEventReceiver : public IEventReceiver {
public:
virtual bool onEvent(const SEvent& event) {
if (event.type == irr::EET_KEY_INPUT_EVENT)
KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
return false;
}
// check whether a key is begin held down
virtual bool IsKeyDown(EKEY_CODE keyCode) const {
return KeyIsDown[keyCode];
}
MyEventReceiver() {
for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
KeyIsDown[i] = false;
}
private:
bool KeyIsDown[KEY_KEY_CODES_COUNT];
}
Then it’s the main part, just like the pevious example, create the device, video driver, and scene manager and camera. And create the event receiver. (MyEventReceiver receiver;)
Create a node moved with the WSAD keys, and set the position and material
scene::ISceneNode *node = smgr->addSphereNode();
if (node) {
node->setPosition(core::vector3df(0,0,30));
node->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp"));
node->setMaterialFlag(video::EMF_LIGHTING, false);
}
Create another node, moveable using a scene node animator
scene::ISceneNode* n = smgr->addCubeSceneNode();
if (n) {
n->setMaterialTexture(0, driver->getTexture("../../media/t351sml.jpg"));
n->setMaterialFlag(video::EMF_LIGHTING, false);
scene::ISceneNodeAnimator* anim =
smgr->createFlyCircleAnimator(core::vector3df(0,0,30), 20.0f);
if (anim)
{
n->addAnimator(anim);
anim->drop();
}
}
The last scene node is to show possibilities of scene node animators is a b3d model, which uses a ‘fly straight’ animator to run between to points.
scene::IAnimatedMeshSceneNode* anms =
smgr->addAnimatedMeshSceneNode(smgr->getMesh("../../media/ninja.b3d"));
if (anms)
{
scene::ISceneNodeAnimator* anim =
smgr->createFlyStraightAnimator(core::vector3df(100, 0, 60),
core::vector3df(-100, 0, 60), 3500, true);
if (anim)
{
anms->addAnimator(anim);
anim->drop();
}
/*
To make the model look right we disable lighting, set the
frames between which the animation should loop, rotate the
model around 180 degrees, and adjust the animation speed and
the texture. To set the right animation (frames and speed), we
would also be able to just call
*/
anms->setMaterialFlag(video::EMF_LIGHTING, false);
anms->setFrameLoop(0, 13);
anms->setAnimationSpeed(15);
anms->setScale(core::vector3df(2.f, 2.f, 2.f));
anms->setRotation(core::vector3df(0, -90, 0));
}
Add the camera and make the mouse cursor invisible
smgr->addCameraSceneNodeFPS();
device->getCurSorControal()->setVisible(false);
Add a logo
device->getGUIEnvironment()->addImage(
driver->getTexture("../../media/irrlichtlogoalpha2.tga"),
core::position2d<s32>(10,20));
gui::IGUIStaticText* diagnostics = device->getGUIEnvironment()->addStaticText(
L"", core::rect<s32>(10, 10, 400, 20));
diagnostics->setOverrideColor(video::SColor(255, 255, 255, 0));
Then draw everything
while (device->run()) {
/* Check if keys W, S, A or D are being held down, and move the sphere node around respectively. */
// Work out a frame delta time.
const u32 now = device->getTimer()->getTime();
const f32 frameDeltaTime = (f32)(now - then) / 1000.f; // Time in seconds
core::vector3df nodePosition = node->getPosition();
if(receiver.IsKeyDown(irr::KEY_KEY_W))
nodePosition.Y += MOVEMENT_SPEED * frameDeltaTime;
else if(receiver.IsKeyDown(irr::KEY_KEY_S))
nodePosition.Y -= MOVEMENT_SPEED * frameDeltaTime;
if(receiver.IsKeyDown(irr::KEY_KEY_A))
nodePosition.X -= MOVEMENT_SPEED * frameDeltaTime;
else if(receiver.IsKeyDown(irr::KEY_KEY_D))
nodePosition.X += MOVEMENT_SPEED * frameDeltaTime;
node->setPosition(nodePosition);
driver->beginScene(true, true, video::SColor(0, 100, 100, 100));
smgr->drawAll();
device->getGUIEnvironment()->drawAll(); // draw the logo
driver->endScene();
}
device->drop();
You can get the complete codes from Github
Compile in MySQL
-- delete a table
DROP TABLE person;
-- create a table
CREATE TABLE person (
id INT(11),
number INT(11),
name VARCHAR(255),
birthday DATE
);
-- insert values
INSERT INTO person VALUES(1, 18, "CECE", "1993-01-23");
INSERT INTO person VALUES(2, 20, "SHAN", "1995-05-15");
INSERT INTO person VALUES(3, 33, "JIN", "1983-07-25");
INSERT INTO person VALUES(4, 12, "XUE", "1973-11-23");
DROP TABLE course;
CREATE TABLE course (
id INT(11),
name VARCHAR(255),
courses VARCHAR(255)
);
INSERT INTO course VALUES(1, "CECE", "COMPUTE");
INSERT INTO course VALUES(2, "SHAN", "math");
INSERT INTO course VALUES(3, "JIN", "english");
-- add some constraints when creating the table
CREATE TABLE fulltable (
sid INT(11) UNIQUE,
name VARCHAR(255) NOT NULL,
age INT(11) CHECK(age>15)
);
-- alter table operations
ALTER TABLE person add GENDER CHAR(255);
ALTER TABLE person change name names CHAR(255);
-- clear all the contents in the table
TRUNCATE TABLE person;
-- delete some rows
DELETE FROM person WHERE id = 1;
-- select
SELECT * FROM person;
SELECT id, number FROM person;
-- drop the duplicate values
SELECT DISTINCT id FROM person;
-- where condition
SELECT id, name, number FROM person WHERE number > 15;
-- and or used in where
SELECT id, name, number FROM person WHERE number > 15 AND id <2;
-- when we are going to look for multiple values
SELECT id, name, number FROM person WHERE id IN (1, 2, 3);
-- between
SELECT id, name, number FROM person WHERE id BETWEEN 1 AND 2;
-- LIKE
SELECT id, name, number FROM person WHERE name LIKE '%CE';
-- sort
SELECT id, name, number FROM person ORDER BY number ASC;
SELECT id, name, number FROM person ORDER BY number DESC;
-- if we have multiple columns to be sorted
SELECT id, name, number FROM person ORDER BY number DESC, id ASC;
-- some math functions
SELECT SUM(number) FROM person;
SELECT COUNT(id) FROM person;
-- not include the duplicate value
SELECT COUNT(DISTINCT id) FROM person;
-- if we need to calculate the sum with the same name
SELECT name, SUM(number) FROM person GROUP BY name;
-- use the value got by the functions, use HAVING
SELECT name, SUM(number) FROM person GROUP BY name HAVING SUM(number);
-- ALIAS for columns or table
-- like after getting the sum(number), change the name into sum
SELECT name, SUM(number) "sum" FROM person GROUP BY name;
-- table join
-- left join, also called inner join, only select the same values
SELECT person.id, person.name, course.courses, sum(person.number) "sum"
FROM person, course
WHERE person.id = course.id
GROUP BY person.id;
-- concatenate
SELECT CONCAT(person.name, course.courses)
FROM person, course
WHERE person.id = 1;
-- substr
SELECT SUBSTR(name, 2, 2)
FROM person
WHERE name = 'CECE';
-- TRIM delete the space in the begining and the end
SELECT TRIM(' sample ');
-- LTRIM, RTRIM
SELECT LTRIM(' sample ');
SELECT RTRIM(' sample ');
-- UNION ======= OR
-- UNION merge two sql results WITHOUT THE duplicate
SELECT id FROM person
UNION
SELECT id FROM course;
-- UNION merge two sql results with THE duplicate
SELECT id FROM person
UNION ALL
SELECT id FROM course;
-- INTERSECT ======= AND
-- in SQL serves, it can be
-- SELECT id FROM person
-- INTERSECT
-- SELECT id FROM course;
-- MINUS:only output the different values in the two sql results
-- SELECT id FROM person
-- MINUS
-- SELECT id FROM course;
-- But in MySQL, there are no INTERSECT AND MINUS, BELOWS it is an example from the internet
-- intersect
SELECT id, nickname, playNum, COUNT(*)
FROM (SELECT id, nickname, playNum
FROM t1
UNION ALL
SELECT id, nickname, playNum
FROM t2
) a
GROUP BY id, nickname, playNum
HAVING COUNT(*) > 1;
-- minus
SELECT t1.id, t1.nickname, t1.playNum
FROM t1 LEFT JOIN t2 ON t1.id = t2.id
WHERE t1.nickname != t2.nickname
OR t1.playNum != t2.playNum;
-- CASE STUDY
-- if-then in SQL
SELECT name, CASE name
WHEN 'CECE' THEN number*2
ELSE number
END
"new_number"
FROM person
-- RANK
-- MEDIUM
-- PERCENTAGE